Skip to content

Commit

Permalink
WIP: design
Browse files Browse the repository at this point in the history
feat: implement Bluetooth Onboarding UI

feat: different 'Not the Trezor you are looking for' UI

feat: implement Bluetooth Onboarding UI 2

feat: implement Bluetooth Onboarding UI

feat: different 'Not the Trezor you are looking for' UI

feat: implement Bluetooth Onboarding UI 2

feat: use CollapsibleBox component in Bluetooth UI

fix: after rebase

enable BT onboarding

WIP: transport name

breaking change

aftr rebase
  • Loading branch information
peter-sanderson authored and szymonlesisz committed Feb 18, 2025
1 parent 66a1a81 commit 232e121
Show file tree
Hide file tree
Showing 32 changed files with 1,104 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ const StyledSkeletonRectangle = styled.div<
>`
width: ${({ $width }) => getValue($width) ?? '80px'};
height: ${({ $height }) => getValue($height) ?? '20px'};
background: ${({ $background, ...props }) => $background ?? mapElevationToBackground(props)};
background: ${({ $background, ...props }) =>
$background ??
mapElevationToBackground({
theme: props.theme,
$elevation: props.$elevation,
})};
border-radius: ${({ $borderRadius }) => getValue($borderRadius) ?? borders.radii.xs};
background-size: 200%;
Expand Down
4 changes: 4 additions & 0 deletions packages/suite-desktop-ui/src/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { useDebugLanguageShortcut, useFormattersConfig } from 'src/hooks/suite';
import history from 'src/support/history';
import { ModalContextProvider } from 'src/support/suite/ModalContext';
import { desktopHandshake } from 'src/actions/suite/suiteActions';
import { initBluetoothThunk } from 'src/actions/bluetooth/initBluetoothThunk';
import * as STORAGE from 'src/actions/suite/constants/storageConstants';

import { DesktopUpdater } from './support/DesktopUpdater';
Expand Down Expand Up @@ -136,6 +137,9 @@ export const init = async (container: HTMLElement) => {
TrezorConnect[method] = proxy[method];
});

// init bluetooth module
await store.dispatch(initBluetoothThunk());

// finally render whole app
root.render(
<ReduxProvider store={store}>
Expand Down
39 changes: 39 additions & 0 deletions packages/suite/src/actions/bluetooth/bluetoothActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createAction } from '@reduxjs/toolkit';

import { BluetoothDevice } from '@trezor/transport-bluetooth';

import {
BluetoothScanStatus,
DeviceBluetoothStatus,
} from '../../reducers/bluetooth/bluetoothReducer';

export const BLUETOOTH_PREFIX = '@suite/bluetooth';

export const bluetoothAdapterEventAction = createAction(
`${BLUETOOTH_PREFIX}/adapter-event`,
({ isPowered }: { isPowered: boolean }) => ({ payload: { isPowered } }),
);

export const bluetoothDeviceListUpdate = createAction(
`${BLUETOOTH_PREFIX}/device-list-update`,
({ devices }: { devices: BluetoothDevice[] }) => ({ payload: { devices } }),
);

export const bluetoothConnectDeviceEventAction = createAction(
`${BLUETOOTH_PREFIX}/device-connection-status`,
({ connectionStatus, id }: { id: string; connectionStatus: DeviceBluetoothStatus }) => ({
payload: { id, connectionStatus },
}),
);

export const bluetoothScanStatusAction = createAction(
`${BLUETOOTH_PREFIX}/scan-status`,
({ status }: { status: BluetoothScanStatus }) => ({ payload: { status } }),
);

export const allBluetoothActions = {
bluetoothAdapterEventAction,
bluetoothDeviceListUpdate,
bluetoothConnectDeviceEventAction,
bluetoothScanStatusAction,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createThunk } from '@suite-common/redux-utils';
import { bluetoothIpc } from '@trezor/transport-bluetooth';

import { BLUETOOTH_PREFIX } from './bluetoothActions';

type ThunkResponse = ReturnType<typeof bluetoothIpc.connectDevice>;

export const bluetoothConnectDeviceThunk = createThunk<ThunkResponse, { id: string }, void>(
`${BLUETOOTH_PREFIX}/bluetoothConnectDeviceThunk`,
async ({ id }, { fulfillWithValue }) => {
const result = await bluetoothIpc.connectDevice(id);

return fulfillWithValue(result);
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createThunk } from '@suite-common/redux-utils';
import { bluetoothIpc } from '@trezor/transport-bluetooth';

import { BLUETOOTH_PREFIX } from './bluetoothActions';

export const bluetoothStartScanningThunk = createThunk<void, void, void>(
`${BLUETOOTH_PREFIX}/bluetoothStartScanningThunk`,
_ => {
// This can fail, but if there is an error we already got it from `adapter-event`
// and user is informed about it (bluetooth turned-off, ...)
bluetoothIpc.startScan();
},
);
12 changes: 12 additions & 0 deletions packages/suite/src/actions/bluetooth/bluetoothStopScanningThunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createThunk } from '@suite-common/redux-utils';
import { bluetoothIpc } from '@trezor/transport-bluetooth';

import { BLUETOOTH_PREFIX } from './bluetoothActions';

export const bluetoothStopScanningThunk = createThunk<void, void, void>(
`${BLUETOOTH_PREFIX}/bluetoothStopScanningThunk`,
_ => {
// This can fail, but there is nothing we can do about it
bluetoothIpc.stopScan();
},
);
55 changes: 55 additions & 0 deletions packages/suite/src/actions/bluetooth/initBluetoothThunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { createThunk } from '@suite-common/redux-utils/';
import { DeviceConnectionStatus, bluetoothIpc } from '@trezor/transport-bluetooth';
import { Without } from '@trezor/type-utils';

import {
BLUETOOTH_PREFIX,
bluetoothAdapterEventAction,
bluetoothConnectDeviceEventAction,
bluetoothDeviceListUpdate,
} from './bluetoothActions';
import { selectSuiteFlags } from '../../reducers/suite/suiteReducer';

type DeviceConnectionStatusWithOptionalId = Without<DeviceConnectionStatus, 'id'> & {
id?: string;
};

export const initBluetoothThunk = createThunk<void, void, void>(
`${BLUETOOTH_PREFIX}/initBluetoothThunk`,
async (_, { dispatch, getState }) => {
const { isBluetoothEnabled } = selectSuiteFlags(getState());

if (!isBluetoothEnabled) {
return;
}

bluetoothIpc.on('adapter-event', isPowered => {
console.warn('adapter-event', isPowered);
dispatch(bluetoothAdapterEventAction({ isPowered }));
});

bluetoothIpc.on('device-list-update', devices => {
console.warn('device-list-update', devices);
dispatch(bluetoothDeviceListUpdate({ devices }));
});

bluetoothIpc.on('device-connection-status', connectionStatus => {
console.warn('device-connection-status', connectionStatus);
const copyConnectionStatus: DeviceConnectionStatusWithOptionalId = {
...connectionStatus,
};
delete copyConnectionStatus.id; // So we dont pollute redux store

dispatch(
bluetoothConnectDeviceEventAction({
id: connectionStatus.id,
connectionStatus: copyConnectionStatus,
}),
);
});

// TODO: this should be called after trezor/connect init?
const knownDevices = getState().bluetooth.pairedDevices;
await bluetoothIpc.init({ knownDevices });
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { DeviceUpdateRequired } from './DeviceUpdateRequired';
import { DeviceUsedElsewhere } from './DeviceUsedElsewhere';
import { MultiShareBackupInProgress } from './MultiShareBackupInProgress';
import { Transport } from './Transport';
import { BluetoothConnect } from '../bluetooth/BluetoothConnect';

const Wrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -106,7 +107,12 @@ export const PrerequisitesGuide = ({ allowSwitchDevice }: PrerequisitesGuideProp
<ElevationContext baseElevation={-1}>
{/* Here we need to draw the inner card with elevation -1 (custom design) */}
<ElevationDown>
<Flex width={470}>Here will be the Bluetooth connection dialog</Flex>
<Flex width={470}>
<BluetoothConnect
onClose={() => setIsBluetoothConnectOpen(false)}
uiMode="spatial"
/>
</Flex>
</ElevationDown>
</ElevationContext>
) : (
Expand Down
Loading

0 comments on commit 232e121

Please sign in to comment.