Skip to content

Commit

Permalink
Merge pull request #166 from lidofinance/feature/dynamic-imports-loaders
Browse files Browse the repository at this point in the history
Add connect button loaders, improve Ledger modal
  • Loading branch information
alx-khramov committed Sep 24, 2024
2 parents 37f1a5b + ff1ae52 commit 1ac8133
Show file tree
Hide file tree
Showing 17 changed files with 205 additions and 77 deletions.
9 changes: 9 additions & 0 deletions packages/connect-wallet-modal/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# @reef-knot/connect-wallet-modal

## 5.5.0

### Minor Changes

- Add the "loading" state for WC and Binance wallet connection buttons;
- Fix the "retry" button for some cases in the Ledger HID connection modal;
- Show a loading spinner in the Ledger modal during ledger packages loading;
- Fix the issue with passing onClickWalletsLess, onClickWalletsMore props;

## 5.4.0

### Minor Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/connect-wallet-modal/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@reef-knot/connect-wallet-modal",
"version": "5.4.0",
"version": "5.5.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
Expand Down Expand Up @@ -46,7 +46,7 @@
"@types/react-dom": "18.2.17"
},
"devDependencies": {
"@reef-knot/core-react": "^4.1.1",
"@reef-knot/core-react": "^4.3.0",
"@reef-knot/types": "^2.0.1",
"@reef-knot/ui-react": "^2.1.1",
"@reef-knot/wallets-helpers": "^2.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { WalletAdapterData, WalletAdapterIcons } from '@reef-knot/types';
import {
ConnectButtonStyle,
ConnectButtonContentStyle,
ConnectButtonLoaderStyle,
ConnectButtonIconStyle,
ConnectButtonTitleStyle,
} from './styles';
Expand All @@ -20,7 +21,14 @@ function isWalletAdapterIcons(
}

const ConnectButton: FC<ConnectButtonProps> = (props: ConnectButtonProps) => {
const { icon, shouldInvertWalletIcon, children, isCompact, ...rest } = props;
const {
icon,
shouldInvertWalletIcon,
children,
isCompact,
isLoading = false,
...rest
} = props;

let ButtonIcon: ElementType = React.Fragment;
if (icon) {
Expand All @@ -33,12 +41,14 @@ const ConnectButton: FC<ConnectButtonProps> = (props: ConnectButtonProps) => {

return (
<ConnectButtonStyle {...rest} type="button">
<ConnectButtonContentStyle>
<ConnectButtonIconStyle $isCompact={isCompact}>
{isValidElement(<ButtonIcon />) && <ButtonIcon />}
</ConnectButtonIconStyle>
<ConnectButtonTitleStyle>{children}</ConnectButtonTitleStyle>
</ConnectButtonContentStyle>
<ConnectButtonLoaderStyle $isLoading={isLoading}>
<ConnectButtonContentStyle>
<ConnectButtonIconStyle $isCompact={isCompact}>
{isValidElement(<ButtonIcon />) && <ButtonIcon />}
</ConnectButtonIconStyle>
<ConnectButtonTitleStyle>{children}</ConnectButtonTitleStyle>
</ConnectButtonContentStyle>
</ConnectButtonLoaderStyle>
</ConnectButtonStyle>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import styled, { css } from '@reef-knot/ui-react/styled-wrapper';
import styled, { css, keyframes } from '@reef-knot/ui-react/styled-wrapper';
import { Button } from '@reef-knot/ui-react';

export const ConnectButtonStyle = styled(Button).attrs({
Expand All @@ -16,16 +16,46 @@ export const ConnectButtonStyle = styled(Button).attrs({
`}
`;

export const ConnectButtonContentStyle = styled.span`
export const ConnectButtonContentStyle = styled.div`
${({ theme }) => css`
display: flex;
flex-direction: row;
align-items: center;
height: 100%;
padding: 0 ${theme.spaceMap.md}px;
color: ${theme.colors.text};
`}
`;

const translation = keyframes`
100% {
background-position: 0 0;
}
`;

export const ConnectButtonLoaderStyle = styled.div<{ $isLoading: boolean }>`
--loader-color: #dfe5eb;
width: 100%;
height: 100%;
animation-name: ${translation};
animation-duration: 1s;
animation-iteration-count: infinite;
animation-play-state: ${({ $isLoading }) =>
$isLoading ? 'running' : 'paused'};
background-size: 300% 100%;
background-position: 100% 0;
background-image: linear-gradient(
90deg,
transparent 0,
transparent 33.33%,
var(--loader-color) 44.44%,
var(--loader-color) 55.55%,
transparent 66.66%,
transparent 100%
);
`;

export const ConnectButtonTitleStyle = styled.div`
${({ theme }) => css`
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import React from 'react';
import { Stack, StackItem, Text, useBreakpoint } from '@lidofinance/lido-ui';
import {
Loader,
Stack,
StackItem,
Text,
useBreakpoint,
} from '@lidofinance/lido-ui';
import { LedgerImageDefault } from './icons/LedgerImageDefault';
import { LedgerImageDefaultMobile } from './icons/LedgerImageDefaultMobile';
import { LedgerScreenContainerStyled } from './styles';
import { useLedgerContext } from './hooks';

export const LedgerConnectionScreen = () => (
<LedgerScreenContainerStyled>
<Stack direction="column" spacing="xl" align="center">
<StackItem>
{useBreakpoint('md') ? (
<LedgerImageDefaultMobile />
) : (
<LedgerImageDefault />
)}
</StackItem>
<StackItem>
<Text color="secondary" size="xs">
Please connect your Ledger and launch Ethereum app on your device
</Text>
</StackItem>
</Stack>
</LedgerScreenContainerStyled>
);
export const LedgerConnectionScreen = () => {
const { isLoadingLedgerLibs } = useLedgerContext();
return (
<LedgerScreenContainerStyled>
<Stack direction="column" spacing="xl" align="center">
<StackItem>
{useBreakpoint('md') ? (
<LedgerImageDefaultMobile />
) : (
<LedgerImageDefault />
)}
</StackItem>
<StackItem>
{isLoadingLedgerLibs ? (
<Loader size="medium" color="secondary" />
) : (
<Text color="secondary" size="xs">
Please connect your Ledger and launch Ethereum app on your device
</Text>
)}
</StackItem>
</Stack>
</LedgerScreenContainerStyled>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type LedgerContextValue = {
transport: MutableRefObject<Transport | null>;
ledgerAppEth: MutableRefObject<Eth | null>;
isTransportConnected: boolean;
isLoadingLedgerLibs: boolean;
error: Error | null;
setError: (e: Error | null) => void;
connectTransport: () => Promise<void>;
Expand All @@ -42,6 +43,7 @@ export const LedgerContextProvider = ({
const ledgerAppEth = useRef<Eth | null>(null);
const [error, setError] = useState<Error | null>(null);
const [isTransportConnected, setIsTransportConnected] = useState(false);
const [isLoadingLedgerLibs, setIsLoadingLedgerLibs] = useState(false);
const [activeAccountsRequestsCounter, setActiveAccountsRequestsCounter] =
useState(0);

Expand Down Expand Up @@ -73,15 +75,20 @@ export const LedgerContextProvider = ({
}

try {
setIsLoadingLedgerLibs(true);
const { default: Eth } = await import('@ledgerhq/hw-app-eth');
setIsLoadingLedgerLibs(false);

transport.current = await getTransport();
isTransportConnecting.current = false;
ledgerAppEth.current = new Eth(transport.current);
await ledgerAppEth.current.getAppConfiguration();
setIsTransportConnected(true);
} catch (e: any) {
await disconnectTransport(true);
setIsLoadingLedgerLibs(false);
setError(helpers.interceptLedgerError(e));
} finally {
isTransportConnecting.current = false;
}
}, [disconnectTransport]);

Expand All @@ -102,6 +109,7 @@ export const LedgerContextProvider = ({
transport,
ledgerAppEth,
isTransportConnected,
isLoadingLedgerLibs,
error,
setError,
connectTransport,
Expand All @@ -111,12 +119,13 @@ export const LedgerContextProvider = ({
setActiveAccountsRequestsCounter,
}),
[
isTransportConnected,
isLoadingLedgerLibs,
error,
connectTransport,
disconnectTransport,
error,
activeAccountsRequestsCounter,
isTransportConnected,
reconnectTransport,
activeAccountsRequestsCounter,
],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { useReefKnotModal } from '@reef-knot/core-react';

export function WalletsModal({
children,
...passedDownProps
...props
}: React.PropsWithChildren<WalletsModalProps>) {
const { metrics, termsLink, privacyNoticeLink } = passedDownProps;
const { metrics, termsLink, privacyNoticeLink } = props;
const { onClickWalletsLess, onClickWalletsMore, ...passedDownProps } = props;

const { currentModal, closeModal, forceCloseAllModals } = useReefKnotModal();

Expand All @@ -33,6 +34,8 @@ export function WalletsModal({
termsProps={termsProps}
onCloseSuccess={onCloseSuccess}
onCloseReject={onCloseReject}
onClickWalletsLess={onClickWalletsLess}
onClickWalletsMore={onClickWalletsMore}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const ConnectWalletModal = ({
} = passedDownProps;

const config = useConfig();
const { walletDataList } = useReefKnotContext();
const { walletDataList, loadingWalletId } = useReefKnotContext();
const { termsChecked } = useReefKnotModal();

const [inputValue, setInputValue] = useState('');
Expand Down Expand Up @@ -117,6 +117,9 @@ export const ConnectWalletModal = ({
const isWalletsToggleButtonShown =
walletsListFull.length > walletsList.length || isShownOtherWallets;

const someWalletIsLoading =
loadingWalletId != null && loadingWalletId.length > 0;

return (
<ConnectWalletModalLayout
inputValue={inputValue}
Expand All @@ -137,7 +140,7 @@ export const ConnectWalletModal = ({
return (
<WalletComponent
key={walletData.walletId}
disabled={!termsChecked}
disabled={!termsChecked || someWalletIsLoading}
onConnect={() => handleConnectSuccess(walletData.walletId)}
shouldInvertWalletIcon={shouldInvertWalletIcon}
metrics={metrics}
Expand Down
34 changes: 11 additions & 23 deletions packages/connect-wallet-modal/src/connectButtons/ConnectBinance.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { FC, useCallback, useState } from 'react';
import { useConnect } from 'wagmi';
import { useDisconnect } from '@reef-knot/core-react';
import React, { FC, useCallback } from 'react';
import { useDisconnect, useReefKnotContext } from '@reef-knot/core-react';
import { ConnectButton } from '../components/ConnectButton';
import { ConnectInjectedProps } from './types';
import { isMobileOrTablet } from '@reef-knot/wallets-helpers';
import { openWindow } from '../helpers/index';
import { useConnectWithLoading } from '../hooks/useConnectWithLoading';

export const ConnectBinance: FC<ConnectInjectedProps> = (
props: ConnectInjectedProps,
Expand All @@ -27,43 +27,30 @@ export const ConnectBinance: FC<ConnectInjectedProps> = (
const metricsOnConnect = metrics?.events?.connect?.handlers[walletId];
const metricsOnClick = metrics?.events?.click?.handlers[walletId];

const { connectAsync } = useConnect();
const { loadingWalletId } = useReefKnotContext();
const { connectWithLoading } = useConnectWithLoading();
const { disconnect } = useDisconnect();

const [binanceModalLoading, setBinanceModalLoading] = useState(false);

const handleConnect = useCallback(async () => {
if (binanceModalLoading) return;

onBeforeConnect?.();
metricsOnClick?.();
disconnect?.();

if (isMobileOrTablet && deeplink && !detector?.()) {
openWindow(deeplink);
} else {
setBinanceModalLoading(true);
await connectAsync(
{ connector },
{
onSettled: () => {
setBinanceModalLoading(false);
},
onSuccess: () => {
onConnect?.();
metricsOnConnect?.();
},
},
);
await connectWithLoading(walletId, { connector });
onConnect?.();
metricsOnConnect?.();
}
}, [
binanceModalLoading,
onBeforeConnect,
metricsOnClick,
disconnect,
deeplink,
detector,
connectAsync,
connectWithLoading,
walletId,
connector,
onConnect,
metricsOnConnect,
Expand All @@ -74,6 +61,7 @@ export const ConnectBinance: FC<ConnectInjectedProps> = (
{...rest}
icon={WalletIcon}
shouldInvertWalletIcon={shouldInvertWalletIcon}
isLoading={loadingWalletId === walletId}
onClick={() => {
void handleConnect();
}}
Expand Down
Loading

0 comments on commit 1ac8133

Please sign in to comment.