Skip to content

Commit

Permalink
💄 (smpl): Rm transport selection, allow to select devices with differ…
Browse files Browse the repository at this point in the history
…ent ones
  • Loading branch information
jdabbech-ledger committed Oct 3, 2024
1 parent 974e35c commit 95dacb9
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 145 deletions.
23 changes: 9 additions & 14 deletions apps/sample/src/components/Device/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const Root = styled(Flex).attrs({ p: 5, mb: 8, borderRadius: 2 })`
background: ${({ theme }: { theme: DefaultTheme }) =>
theme.colors.neutral.c30};
align-items: center;
border: ${({ active, theme }: { theme: DefaultTheme; active: boolean }) =>
`1px solid ${active ? theme.colors.success.c40 : "transparent"}`};
cursor: ${({ active }: { active: boolean }) =>
active ? "normal" : "pointer"};
`;

const IconContainer = styled(Flex).attrs({ p: 4, mr: 3, borderRadius: 100 })`
Expand All @@ -42,6 +46,7 @@ type DeviceProps = {
sessionId: DeviceSessionId;
model: DeviceModelId;
onDisconnect: () => Promise<void>;
onSelect: () => void;
};

function getIconComponent(model: DeviceModelId) {
Expand All @@ -60,16 +65,17 @@ export const Device: React.FC<DeviceProps> = ({
type,
model,
onDisconnect,
onSelect,
sessionId,
}) => {
const sessionState = useDeviceSessionState(sessionId);
const {
state: { deviceById, selectedId },
dispatch,
state: { selectedId },
} = useDeviceSessionsContext();
const IconComponent = getIconComponent(model);
const isActive = selectedId === sessionId;
return (
<Root>
<Root active={isActive} onClick={isActive ? undefined : onSelect}>
<IconContainer>
<IconComponent size="S" />
</IconContainer>
Expand Down Expand Up @@ -98,17 +104,6 @@ export const Device: React.FC<DeviceProps> = ({
</Box>
<div data-testid="dropdown_device-option">
<DropdownGeneric closeOnClickOutside label="" placement="bottom">
{Object.values(deviceById).length > 1 && selectedId !== sessionId && (
<ActionRow
onClick={() =>
dispatch({ type: "select_session", payload: { sessionId } })
}
>
<Text variant="paragraph" color="neutral.c80">
Select
</Text>
</ActionRow>
)}
<ActionRow data-testid="CTA_disconnect-device" onClick={onDisconnect}>
<Text variant="paragraph" color="neutral.c80">
Disconnect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ export const AllDeviceActions: React.FC<{ sessionId: string }> = ({
const deviceModelId = sdk.getConnectedDevice({
sessionId,
}).modelId;
console.log(
"sdk get connected device::",
sdk.getConnectedDevice({ sessionId }),
);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const deviceActions: DeviceActionProps<any, any, any, any>[] = useMemo(
Expand Down Expand Up @@ -155,7 +151,7 @@ export const AllDeviceActions: React.FC<{ sessionId: string }> = ({
ListAppsWithMetadataDAIntermediateValue
>,
],
[],
[sessionId, deviceModelId],
);

return (
Expand Down
114 changes: 35 additions & 79 deletions apps/sample/src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useCallback, useState } from "react";
import {
Button,
Dropdown,
DropdownGeneric,
Flex,
Icons,
Input,
Switch,
} from "@ledgerhq/react-ui";
import styled, { DefaultTheme } from "styled-components";
import { useSdkConfigContext } from "../../providers/SdkConfig";
import { useSdkConfigContext } from "@/providers/SdkConfig";
import { BuiltinTransports } from "@ledgerhq/device-management-kit";

const Root = styled(Flex).attrs({ py: 3, px: 10, gridGap: 8 })`
Expand All @@ -33,50 +33,25 @@ const UrlInput = styled(Input)`
align-items: center;
`;

type DropdownOption = {
label: string;
value: BuiltinTransports;
};

const DropdownValues: DropdownOption[] = [
{
label: "USB",
value: BuiltinTransports.USB,
},
{
label: "BLE",
value: BuiltinTransports.BLE,
},
{
label: "Mock server",
value: BuiltinTransports.MOCK_SERVER,
},
];

export const Header = () => {
const {
dispatch,
state: { transport, mockServerUrl },
} = useSdkConfigContext();
const onChangeTransport = useCallback(
(selectedValue: DropdownOption | null) => {
if (selectedValue) {
dispatch({
type: "set_transport",
payload: { transport: selectedValue.value },
});
}
},
[],
);
const onToggleMockServer = useCallback(() => {
dispatch({
type: "set_transport",
payload: {
transport:
transport === BuiltinTransports.MOCK_SERVER
? BuiltinTransports.USB
: BuiltinTransports.MOCK_SERVER,
},
});
}, [transport]);
const [mockServerStateUrl, setMockServerStateUrl] =
useState<string>(mockServerUrl);

const getDropdownValue = useCallback(
(transport: BuiltinTransports): DropdownOption | undefined =>
DropdownValues.find((option) => option.value === transport),
[],
);
const mockServerEnabled = transport === BuiltinTransports.MOCK_SERVER;

const validateServerUrl = useCallback(
() =>
Expand All @@ -98,48 +73,29 @@ export const Header = () => {
</Actions>
<div data-testid="dropdown_mock-server-switch">
<DropdownGeneric closeOnClickOutside label="" placement="bottom">
<Flex
my={5}
py={6}
px={5}
width={280}
height={100}
justifyContent="center"
flexDirection="column"
>
<Dropdown
label="Transport"
onChange={onChangeTransport}
options={[
{
label: "USB",
value: BuiltinTransports.USB,
},
{
label: "BLE",
value: BuiltinTransports.BLE,
},
{
label: "Mock server",
value: BuiltinTransports.MOCK_SERVER,
},
]}
value={getDropdownValue(transport)}
/>
{transport === BuiltinTransports.MOCK_SERVER && (
<UrlInput
value={mockServerStateUrl}
onChange={(url: string) => setMockServerStateUrl(url)}
renderRight={() => (
<Flex alignItems="center" justifyContent="stretch">
<Button iconButton onClick={validateServerUrl}>
<Icons.CheckmarkCircleFill size="S" />
</Button>
</Flex>
)}
<Flex my={5} py={6} px={5} width={280}>
<div data-testid="switch_mock-server">
<Switch
onChange={onToggleMockServer}
checked={mockServerEnabled}
name="switch-mock-server"
label="Enable Mock server"
/>
)}
</div>
</Flex>
{mockServerEnabled && (
<UrlInput
value={mockServerStateUrl}
onChange={(url: string) => setMockServerStateUrl(url)}
renderRight={() => (
<Flex alignItems="center" justifyContent="stretch">
<Button iconButton onClick={validateServerUrl}>
<Icons.CheckmarkCircleFill size="S" />
</Button>
</Flex>
)}
/>
)}
</DropdownGeneric>
</div>
</Root>
Expand Down
91 changes: 91 additions & 0 deletions apps/sample/src/components/MainView/ConnectDeviceActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Button, Flex } from "@ledgerhq/react-ui";
import { BuiltinTransports, SdkError } from "@ledgerhq/device-management-kit";
import React, { useCallback } from "react";
import { useSdkConfigContext } from "@/providers/SdkConfig";
import { useSdk } from "@/providers/DeviceSdkProvider";
import { useDeviceSessionsContext } from "@/providers/DeviceSessionsProvider";

type ConnectDeviceActionsProps = {
onError: (error: SdkError | null) => void;
};

export const ConnectDeviceActions = ({
onError,
}: ConnectDeviceActionsProps) => {
const {
dispatch: dispatchSdkConfig,
state: { transport },
} = useSdkConfigContext();
const { dispatch: dispatchDeviceSession } = useDeviceSessionsContext();
const sdk = useSdk();

const onSelectDeviceClicked = useCallback(
(selectedTransport: BuiltinTransports) => {
onError(null);
dispatchSdkConfig({
type: "set_transport",
payload: { transport: selectedTransport },
});
sdk.startDiscovering({ transport: selectedTransport }).subscribe({
next: (device) => {
sdk
.connect({ device })
.then((sessionId) => {
console.log(
`🦖 Response from connect: ${JSON.stringify(sessionId)} 🎉`,
);
dispatchDeviceSession({
type: "add_session",
payload: {
sessionId,
connectedDevice: sdk.getConnectedDevice({ sessionId }),
},
});
})
.catch((error) => {
onError(error);
console.error(`Error from connection or get-version`, error);
});
},
error: (error) => {
console.error(error);
},
});
},
[sdk, transport],
);

return transport === BuiltinTransports.MOCK_SERVER ? (
<Button
mx={3}
onClick={() => onSelectDeviceClicked(BuiltinTransports.MOCK_SERVER)}
variant="main"
backgroundColor="main"
size="large"
data-testid="CTA_select-device"
>
Select a device
</Button>
) : (
<Flex>
<Button
mx={3}
onClick={() => onSelectDeviceClicked(BuiltinTransports.USB)}
variant="main"
backgroundColor="main"
size="large"
>
Select a USB device
</Button>
<Button
mx={3}
onClick={() => onSelectDeviceClicked(BuiltinTransports.BLE)}
variant="main"
backgroundColor="main"
size="large"
>
Select a BLE device
</Button>
</Flex>
);
};
Loading

0 comments on commit 95dacb9

Please sign in to comment.