Skip to content

Commit 1377622

Browse files
feat(suite): added bluetooth adapter status modal and no trezor found modal
1 parent d89a0d3 commit 1377622

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { useState } from 'react';
2+
3+
import { TranslationKey } from '@suite-common/intl-types';
4+
import { Button, Flex, Modal, Text } from '@trezor/components';
5+
import { desktopApi } from '@trezor/suite-desktop-api';
6+
import { spacings } from '@trezor/theme';
7+
8+
import { Translation } from 'src/components/suite/Translation';
9+
10+
type BluetoothAdapterStatusModalProps = {
11+
bluetoothAdapterStatus: 'disabled' | 'permission-denied' | 'not-compatible';
12+
onCancel: () => void;
13+
};
14+
15+
type AdapterIssueSolution = {
16+
title: TranslationKey;
17+
description: TranslationKey;
18+
ctaText?: TranslationKey;
19+
onCtaClick?: () => void;
20+
deeplinkFailed?: TranslationKey;
21+
};
22+
23+
export const BluetoothAdapterStatusModal = ({
24+
bluetoothAdapterStatus,
25+
onCancel,
26+
}: BluetoothAdapterStatusModalProps) => {
27+
const [hasDeeplinkFailed, setHasDeeplinkFailed] = useState(false);
28+
29+
const openBluetoothSettings = async (settingsPage: 'bluetooth' | 'bluetooth-permissions') => {
30+
const opened = await desktopApi.openSystemSettings(settingsPage);
31+
if (!opened.success) {
32+
setHasDeeplinkFailed(true);
33+
}
34+
};
35+
const openBluetoothEnableSettings = () => {
36+
openBluetoothSettings('bluetooth');
37+
};
38+
const openBluetoothSecuritySettings = () => {
39+
openBluetoothSettings('bluetooth-permissions');
40+
};
41+
42+
const statuses: Record<string, AdapterIssueSolution> = {
43+
disabled: {
44+
title: 'TR_BLUETOOTH_TURNED_OFF',
45+
description: 'TR_BLUETOOTH_TURNED_OFF_TEXT',
46+
ctaText: 'TR_BLUETOOTH_SETTINGS',
47+
onCtaClick: openBluetoothEnableSettings,
48+
deeplinkFailed: 'TR_BLUETOOTH_CANNOT_OPEN_BLUETOOTH_SETTINGS',
49+
},
50+
'permission-denied': {
51+
title: 'TR_BLUETOOTH_ALLOW_BLUETOOTH_PERMISSIONS',
52+
description: 'TR_BLUETOOTH_OR_CONNECT_VIA_CABLE',
53+
ctaText: 'TR_BLUETOOTH_SETTINGS',
54+
onCtaClick: openBluetoothSecuritySettings,
55+
deeplinkFailed: 'TR_BLUETOOTH_CANNOT_OPEN_BLUETOOTH_SETTINGS_PERMISSIONS',
56+
},
57+
'not-compatible': {
58+
title: 'TR_BLUETOOTH_VERSION_NOT_COMPATIBLE_LINE1',
59+
description: 'TR_BLUETOOTH_VERSION_NOT_COMPATIBLE_LINE2',
60+
},
61+
};
62+
63+
const status = statuses[bluetoothAdapterStatus];
64+
65+
return (
66+
<Modal
67+
heading={<Translation id={status.title} />}
68+
onCancel={onCancel}
69+
bottomContent={
70+
<>
71+
{status.ctaText && (
72+
<Button isDisabled={hasDeeplinkFailed} onClick={status.onCtaClick}>
73+
<Translation id={status.ctaText} />
74+
</Button>
75+
)}
76+
<Button onClick={onCancel} variant="tertiary">
77+
<Translation id="TR_CANCEL" />
78+
</Button>
79+
</>
80+
}
81+
>
82+
<Flex gap={spacings.md} direction="column">
83+
<Text>
84+
<Translation id={status.description}></Translation>
85+
</Text>
86+
87+
{hasDeeplinkFailed && status.deeplinkFailed && (
88+
<Text variant="warning">
89+
<Translation id={status.deeplinkFailed} />
90+
</Text>
91+
)}
92+
</Flex>
93+
</Modal>
94+
);
95+
};
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { useMemo } from 'react';
2+
3+
import { Button, Modal } from '@trezor/components';
4+
import { isDesktop } from '@trezor/env-utils';
5+
import { TREZOR_SUPPORT_URL } from '@trezor/urls';
6+
7+
import { Translation } from 'src/components/suite/Translation';
8+
import { TroubleshootingTipsItem } from 'src/components/suite/troubleshooting/TroubleshootingTips';
9+
import { TroubleshootingTipsList } from 'src/components/suite/troubleshooting/TroubleshootingTipsList';
10+
import {
11+
TROUBLESHOOTING_ALL_BLUETOOTH_TIPS,
12+
TROUBLESHOOTING_TIP_BRIDGE_STATUS,
13+
TROUBLESHOOTING_TIP_CABLE,
14+
TROUBLESHOOTING_TIP_DIFFERENT_COMPUTER,
15+
TROUBLESHOOTING_TIP_SUITE_DESKTOP,
16+
TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE,
17+
TROUBLESHOOTING_TIP_UDEV,
18+
TROUBLESHOOTING_TIP_USB,
19+
} from 'src/components/suite/troubleshooting/tips';
20+
import { useSelector } from 'src/hooks/suite';
21+
import { useBridgeDesktopApi } from 'src/hooks/suite/useBridgeDesktopApi';
22+
import { selectHasTransportOfType } from 'src/selectors/suite/suiteSelectors';
23+
24+
type DontSeeYourTrezorModalProps = {
25+
isBluetoothMode: boolean;
26+
onGoBack?: () => void;
27+
};
28+
29+
const commonCableTips = [
30+
TROUBLESHOOTING_TIP_UDEV,
31+
TROUBLESHOOTING_TIP_CABLE,
32+
TROUBLESHOOTING_TIP_USB,
33+
];
34+
35+
export const DontSeeYourTrezorModal = ({
36+
onGoBack,
37+
isBluetoothMode,
38+
}: DontSeeYourTrezorModalProps) => {
39+
const isWebUsbTransport = useSelector(selectHasTransportOfType('WebUsbTransport'));
40+
41+
const bridgeDesktopApi = useBridgeDesktopApi();
42+
43+
const openTrezorSupport = () => {
44+
window.open(TREZOR_SUPPORT_URL, '_blank');
45+
onGoBack?.();
46+
};
47+
48+
const cableItem: TroubleshootingTipsItem[] = useMemo(() => {
49+
const items = isWebUsbTransport
50+
? [...commonCableTips, TROUBLESHOOTING_TIP_SUITE_DESKTOP]
51+
: [
52+
TROUBLESHOOTING_TIP_BRIDGE_STATUS,
53+
...commonCableTips,
54+
TROUBLESHOOTING_TIP_DIFFERENT_COMPUTER,
55+
];
56+
57+
if (bridgeDesktopApi?.bridgeProcess?.process) {
58+
items.push(TROUBLESHOOTING_TIP_SUITE_DESKTOP_TOGGLE_BRIDGE);
59+
} else {
60+
// TODO: here we are going to put instruction to uninstall standalone bridge
61+
}
62+
63+
return items;
64+
}, [isWebUsbTransport, bridgeDesktopApi]);
65+
66+
const tipItems = useMemo(() => {
67+
if (isBluetoothMode && isDesktop()) {
68+
return TROUBLESHOOTING_ALL_BLUETOOTH_TIPS;
69+
}
70+
71+
return cableItem;
72+
}, [isBluetoothMode, cableItem]);
73+
74+
return (
75+
<Modal
76+
bottomContent={
77+
<>
78+
<Button onClick={onGoBack} variant="info">
79+
<Translation
80+
id={isBluetoothMode ? 'TR_BLUETOOTH_SCAN_AGAIN' : 'TR_GOT_IT'}
81+
/>
82+
</Button>
83+
<Button
84+
variant="tertiary"
85+
onClick={isBluetoothMode ? onGoBack : openTrezorSupport}
86+
>
87+
<Translation
88+
id={isBluetoothMode ? 'TR_CANCEL' : 'TR_CONTACT_TREZOR_SUPPORT'}
89+
/>
90+
</Button>
91+
</>
92+
}
93+
heading={<Translation id="TR_STILL_DONT_SEE_YOUR_TREZOR" />}
94+
onCancel={onGoBack}
95+
>
96+
<TroubleshootingTipsList items={tipItems} />
97+
</Modal>
98+
);
99+
};

0 commit comments

Comments
 (0)