Skip to content

Commit b776eac

Browse files
feat: Add bluetooth debug-settings
1 parent ab01532 commit b776eac

File tree

7 files changed

+132
-13
lines changed

7 files changed

+132
-13
lines changed

packages/suite/src/actions/suite/__fixtures__/suiteActions.ts

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ const initialRun = [
214214
showCopyAddressModal: true,
215215
showUnhideTokenModal: true,
216216
enableAutoupdateOnNextRun: false,
217+
isBluetoothEnabled: false,
217218
},
218219
},
219220
},

packages/suite/src/components/suite/PrerequisitesGuide/DeviceConnect.tsx

+36-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Button } from '@trezor/components';
2+
13
import { Translation, TroubleshootingTips, WebUsbButton } from 'src/components/suite';
24
import {
35
TROUBLESHOOTING_TIP_BRIDGE_STATUS,
@@ -8,11 +10,42 @@ import {
810
TROUBLESHOOTING_TIP_USB,
911
} from 'src/components/suite/troubleshooting/tips';
1012

13+
import { useSelector } from '../../../hooks/suite';
14+
import { selectHasTransportOfType, selectSuiteFlags } from '../../../reducers/suite/suiteReducer';
15+
16+
const CallToActionButton = ({ onBluetoothClick }: { onBluetoothClick: () => void }) => {
17+
const { isBluetoothEnabled } = useSelector(selectSuiteFlags);
18+
const isWebUsbTransport = useSelector(selectHasTransportOfType('WebUsbTransport'));
19+
20+
if (isBluetoothEnabled) {
21+
return (
22+
<Button
23+
variant="tertiary"
24+
size="tiny"
25+
onClick={e => {
26+
e.stopPropagation();
27+
onBluetoothClick();
28+
}}
29+
>
30+
<Translation id="TR_CONNECT_BLUETOOTH_BUTTON" />
31+
</Button>
32+
);
33+
}
34+
35+
if (isWebUsbTransport) {
36+
return <WebUsbButton data-testid="@webusb-button" />;
37+
}
38+
39+
return null;
40+
};
41+
1142
interface DeviceConnectProps {
12-
isWebUsbTransport: boolean;
43+
onBluetoothClick: () => void;
1344
}
1445

15-
export const DeviceConnect = ({ isWebUsbTransport }: DeviceConnectProps) => {
46+
export const DeviceConnect = ({ onBluetoothClick }: DeviceConnectProps) => {
47+
const isWebUsbTransport = useSelector(selectHasTransportOfType('WebUsbTransport'));
48+
1649
const items = isWebUsbTransport
1750
? [
1851
TROUBLESHOOTING_TIP_UDEV,
@@ -32,7 +65,7 @@ export const DeviceConnect = ({ isWebUsbTransport }: DeviceConnectProps) => {
3265
<TroubleshootingTips
3366
label={<Translation id="TR_STILL_DONT_SEE_YOUR_TREZOR" />}
3467
items={items}
35-
cta={isWebUsbTransport ? <WebUsbButton data-testid="@webusb-button" /> : undefined}
68+
cta={<CallToActionButton onBluetoothClick={onBluetoothClick} />}
3669
data-testid="@connect-device-prompt/no-device-detected"
3770
/>
3871
);

packages/suite/src/components/suite/PrerequisitesGuide/PrerequisitesGuide.tsx

+42-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import { useMemo } from 'react';
1+
import { useMemo, useState } from 'react';
22

33
import { motion } from 'framer-motion';
44
import styled from 'styled-components';
55

66
import { deviceNeedsAttention, getStatus } from '@suite-common/suite-utils';
77
import { selectDevices, selectSelectedDevice } from '@suite-common/wallet-core';
8-
import { Button, motionEasing } from '@trezor/components';
8+
import { Button, ElevationContext, ElevationDown, Flex, motionEasing } from '@trezor/components';
99

1010
import { goto } from 'src/actions/suite/routerActions';
1111
import { ConnectDevicePrompt, Translation } from 'src/components/suite';
1212
import { useDispatch, useSelector } from 'src/hooks/suite';
13-
import { selectHasTransportOfType, selectPrerequisite } from 'src/reducers/suite/suiteReducer';
13+
import { selectPrerequisite } from 'src/reducers/suite/suiteReducer';
1414

1515
import { DeviceAcquire } from './DeviceAcquire';
1616
import { DeviceBootloader } from './DeviceBootloader';
@@ -43,16 +43,25 @@ const ButtonWrapper = styled.div`
4343
margin-top: 30px;
4444
`;
4545

46-
interface PrerequisitesGuideProps {
46+
const Bluetooth = () => (
47+
<ElevationContext baseElevation={-1}>
48+
{/* Here we need to draw the inner card with elevation -1 (custom design) */}
49+
<ElevationDown>
50+
<Flex width={470}>Here will be the Bluetooth connection dialog</Flex>
51+
</ElevationDown>
52+
</ElevationContext>
53+
);
54+
55+
type NonBluetoothProps = {
4756
allowSwitchDevice?: boolean;
48-
}
57+
setIsBluetoothConnectOpen: (isOpen: boolean) => void;
58+
};
4959

50-
export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProps) => {
60+
const NonBluetooth = ({ allowSwitchDevice, setIsBluetoothConnectOpen }: NonBluetoothProps) => {
5161
const dispatch = useDispatch();
5262
const device = useSelector(selectSelectedDevice);
5363
const devices = useSelector(selectDevices);
5464
const connectedDevicesCount = devices.filter(d => d.connected === true).length;
55-
const isWebUsbTransport = useSelector(selectHasTransportOfType('WebUsbTransport'));
5665
const prerequisite = useSelector(selectPrerequisite);
5766

5867
const TipComponent = useMemo(
@@ -63,7 +72,9 @@ export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProp
6372
case 'device-disconnect-required':
6473
return <DeviceDisconnectRequired />;
6574
case 'device-disconnected':
66-
return <DeviceConnect isWebUsbTransport={isWebUsbTransport} />;
75+
return (
76+
<DeviceConnect onBluetoothClick={() => setIsBluetoothConnectOpen(true)} />
77+
);
6778
case 'device-unacquired':
6879
return <DeviceAcquire />;
6980
case 'device-used-elsewhere':
@@ -91,14 +102,14 @@ export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProp
91102
return <></>;
92103
}
93104
},
94-
[prerequisite, isWebUsbTransport, device],
105+
[prerequisite, device, setIsBluetoothConnectOpen],
95106
);
96107

97108
const handleSwitchDeviceClick = () =>
98109
dispatch(goto('suite-switch-device', { params: { cancelable: true } }));
99110

100111
return (
101-
<Wrapper>
112+
<>
102113
<ConnectDevicePrompt
103114
connected={!!device}
104115
showWarning={
@@ -123,6 +134,27 @@ export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProp
123134
>
124135
<TipComponent />
125136
</TipsContainer>
137+
</>
138+
);
139+
};
140+
141+
interface PrerequisitesGuideProps {
142+
allowSwitchDevice?: boolean;
143+
}
144+
145+
export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProps) => {
146+
const [isBluetoothConnectOpen, setIsBluetoothConnectOpen] = useState(false);
147+
148+
return (
149+
<Wrapper>
150+
{isBluetoothConnectOpen ? (
151+
<Bluetooth />
152+
) : (
153+
<NonBluetooth
154+
allowSwitchDevice={allowSwitchDevice}
155+
setIsBluetoothConnectOpen={setIsBluetoothConnectOpen}
156+
/>
157+
)}
126158
</Wrapper>
127159
);
128160
};

packages/suite/src/reducers/suite/suiteReducer.ts

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export interface Flags {
8585
showUnhideTokenModal: boolean;
8686
showCopyAddressModal: boolean;
8787
enableAutoupdateOnNextRun: boolean;
88+
isBluetoothEnabled: boolean;
8889
}
8990

9091
export interface EvmSettings {
@@ -164,6 +165,7 @@ const initialState: SuiteState = {
164165
showCopyAddressModal: true,
165166
showUnhideTokenModal: true,
166167
enableAutoupdateOnNextRun: false,
168+
isBluetoothEnabled: false,
167169
},
168170
evmSettings: {
169171
confirmExplanationModalClosed: {},

packages/suite/src/support/messages.ts

+8
Original file line numberDiff line numberDiff line change
@@ -9492,4 +9492,12 @@ export default defineMessages({
94929492
id: 'TR_WALLTCONNECT_SESSIONS',
94939493
defaultMessage: 'Sessions',
94949494
},
9495+
TR_BLUETOOTH: {
9496+
id: 'TR_BLUETOOTH',
9497+
defaultMessage: 'Bluetooth',
9498+
},
9499+
TR_CONNECT_BLUETOOTH_BUTTON: {
9500+
id: 'TR_CONNECT_BLUETOOTH_BUTTON',
9501+
defaultMessage: 'Connect Safe 7 via bluetooth',
9502+
},
94959503
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { useState } from 'react';
2+
3+
import { Checkbox } from '@trezor/components';
4+
5+
import { ActionColumn, SectionItem, TextColumn } from 'src/components/suite';
6+
import { useDispatch, useSelector } from 'src/hooks/suite';
7+
8+
// import { initBluetoothThunk } from '../../../actions/bluetooth/initBluetoothThunk';
9+
import { setFlag } from '../../../actions/suite/suiteActions';
10+
import { selectSuiteFlags } from '../../../reducers/suite/suiteReducer';
11+
12+
export const Bluetooth = () => {
13+
const { isBluetoothEnabled } = useSelector(selectSuiteFlags);
14+
const dispatch = useDispatch();
15+
const [isLoading, setIsLoading] = useState(false);
16+
17+
const handleOnClick = () => {
18+
setIsLoading(true);
19+
dispatch(setFlag('isBluetoothEnabled', !isBluetoothEnabled));
20+
// await dispatch(initBluetoothThunk());
21+
setIsLoading(false);
22+
};
23+
24+
return (
25+
<SectionItem>
26+
<TextColumn title="Bluetooth enabled" />
27+
<ActionColumn>
28+
<Checkbox
29+
isDisabled={isLoading}
30+
isChecked={isBluetoothEnabled}
31+
onClick={handleOnClick}
32+
/>
33+
</ActionColumn>
34+
</SectionItem>
35+
);
36+
};

packages/suite/src/views/settings/SettingsDebug/SettingsDebug.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { isDesktop, isWeb } from '@trezor/env-utils';
22

33
import { SettingsLayout, SettingsSection } from 'src/components/settings';
4+
import { Translation } from 'src/components/suite';
45
import { useSelector } from 'src/hooks/suite';
56
import { selectSuiteFlags } from 'src/reducers/suite/suiteReducer';
67

78
import { Backends } from './Backends';
9+
import { Bluetooth } from './Bluetooth';
810
import { CheckFirmwareAuthenticity } from './CheckFirmwareAuthenticity';
911
import { CoinjoinApi } from './CoinjoinApi';
1012
import { DeviceAuthenticity } from './DeviceAuthenticity';
@@ -88,6 +90,11 @@ export const SettingsDebug = () => {
8890
<SettingsSection title="WalletConnect">
8991
<WalletConnect />
9092
</SettingsSection>
93+
{isDesktop() && (
94+
<SettingsSection title={<Translation id="TR_BLUETOOTH" />}>
95+
<Bluetooth />
96+
</SettingsSection>
97+
)}
9198
</SettingsLayout>
9299
);
93100
};

0 commit comments

Comments
 (0)