Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Router, errorAtom, renderLogic #181

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/widget-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"lodash.debounce": "^4.0.8",
"pluralize": "^8.0.0",
"rc-virtual-list": "^3.14.5",
"react-error-boundary": "^4.0.13",
"react-shadow-scope": "^1.0.5",
"zod": "^3.23.8"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/widget-v2/src/components/AssetChainInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useTheme } from 'styled-components';
import { CogIcon } from '@/icons/CogIcon';
import { Button, GhostButton } from '@/components/Button';
import { useAtom } from 'jotai';
import { skipAssets } from '@/state/skip';
import { skipAssets } from '@/state/skipClient';
import { useUsdValue } from '@/utils/useUsdValue';
import { formatUSD } from '@/utils/intl';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import {
import { WALLET_LIST } from '@/modals/WalletSelectorModal/WalletSelectorFlow';
import { Button } from '@/components/Button';
import { SmallText, Text } from '@/components/Typography';
import { destinationAssetAtom, destinationWalletAtom } from '@/state/swap';
import { destinationAssetAtom, destinationWalletAtom } from '@/state/swapPage';
import { useAtom } from 'jotai';
import { getChain } from '@/state/skip';
import { getChain } from '@/state/skipClient';

export const ManualAddressModal = NiceModal.create((modalProps: ModalProps) => {
const { theme } = modalProps;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Modal, ModalProps } from '@/components/Modal';
import { Column } from '@/components/Layout';
import { styled } from 'styled-components';
import { useAtom } from 'jotai';
import { ChainWithAsset, ClientAsset, skipAssets } from '@/state/skip';
import { ChainWithAsset, ClientAsset, skipAssets } from '@/state/skipClient';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { VirtualList } from '@/components/VirtualList';
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Row } from '@/components/Layout';
import { ModalRowItem } from '@/components/ModalRowItem';
import { SmallText, Text } from '@/components/Typography';
import { ChainWithAsset, ClientAsset } from '@/state/skip';
import { ChainWithAsset, ClientAsset } from '@/state/skipClient';
import { CircleSkeletonElement, SkeletonElement } from '@/components/Skeleton';
import { styled } from 'styled-components';
import { Chain } from '@chain-registry/types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SkipLogoIcon } from '@/icons/SkipLogoIcon';
import { SmallText } from '@/components/Typography';
import { SearchIcon } from '@/icons/SearchIcon';
import { StyledAssetLabel } from '@/components/AssetChainInput';
import { ClientAsset } from '@/state/skip';
import { ClientAsset } from '@/state/skipClient';
import { LeftArrowIcon } from '@/icons/ArrowIcon';
import { useModal } from '@ebay/nice-modal-react';
import { Button } from '@/components/Button';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RouteResponse } from '@skip-go/client';
import { SmallText } from '@/components/Typography';
import { useAtom } from 'jotai';
import { skipAssets, getChain, ClientAsset } from '@/state/skip';
import { skipAssets, getChain, ClientAsset } from '@/state/skipClient';
import { Column, Row } from '@/components/Layout';
import styled, { useTheme } from 'styled-components';
import { getFormattedAssetAmount } from '@/utils/crypto';
Expand Down
13 changes: 13 additions & 0 deletions packages/widget-v2/src/pages/ErrorPage/ErrorPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { errorAtom } from '@/state/errorPage';
import { useResetAtom } from 'jotai/utils';

export const ErrorPage = () => {
const resetError = useResetAtom(errorAtom);

return (
<div>
error page
<button onClick={() => resetError()}>reset</button>
</div>
);
};
Comment on lines +1 to +13
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is temp, i created a ticket to actually create the ErrorPage properly

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useModal } from '@ebay/nice-modal-react';
import { ManualAddressModal } from '@/modals/ManualAddressModal/ManualAddressModal';
import styled, { useTheme } from 'styled-components';
import { useAtom } from 'jotai';
import { destinationWalletAtom } from '@/state/swap';
import { destinationWalletAtom } from '@/state/swapPage';
import { SwapExecutionPageRouteSimple } from './SwapExecutionPageRouteSimple';
import { SwapExecutionPageRouteDetailed } from './SwapExecutionPageRouteDetailed';

Expand All @@ -17,6 +17,7 @@ import { Operation, txState } from './SwapExecutionPageRouteDetailedRow';
import { SmallText } from '@/components/Typography';
import { SignatureIcon } from '@/icons/SignatureIcon';
import pluralize from 'pluralize';
import operations from './operations.json';

enum SwapExecutionState {
destinationAddressUnset,
Expand All @@ -25,14 +26,10 @@ enum SwapExecutionState {
confirmed,
}

export type SwapExecutionPageProps = {
operations: Operation[];
};

const SIGNATURES_REQUIRED = 2;
const TX_DELAY_MS = 5_000; // 5 seconds

export const SwapExecutionPage = ({ operations }: SwapExecutionPageProps) => {
export const SwapExecutionPage = () => {
const theme = useTheme();

const [destinationWallet] = useAtom(destinationWalletAtom);
Expand Down Expand Up @@ -157,7 +154,10 @@ export const SwapExecutionPage = ({ operations }: SwapExecutionPageProps) => {
onClick: () => setSimpleRoute(!simpleRoute),
}}
/>
<SwapExecutionPageRoute txStateMap={txStateMap} operations={operations} />
<SwapExecutionPageRoute
txStateMap={txStateMap}
operations={operations as Operation[]}
/>
{renderMainButton}
<SwapPageFooter
rightContent={
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useAtom } from 'jotai';
import { Row } from '@/components/Layout';
import { SmallText } from '@/components/Typography';
import { getChain, skipAssets } from '@/state/skip';
import { getChain, skipAssets } from '@/state/skipClient';
import { getFormattedAssetAmount } from '@/utils/crypto';
import { css, styled, useTheme } from 'styled-components';
import React from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAtom } from 'jotai';
import { SwapExecutionPageRouteSimpleRow } from './SwapExecutionPageRouteSimpleRow';
import { BridgeArrowIcon } from '@/icons/BridgeArrowIcon';
import { ICONS } from '@/icons';
import { destinationWalletAtom } from '@/state/swap';
import { destinationWalletAtom } from '@/state/swapPage';
import { WALLET_LIST } from '@/modals/WalletSelectorModal/WalletSelectorFlow';

export type SwapExecutionPageRouteSimpleProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useTheme } from 'styled-components';
import { Button } from '@/components/Button';
import { Column, Row } from '@/components/Layout';
import { SmallText, Text } from '@/components/Typography';
import { getChain, skipAssets } from '@/state/skip';
import { getChain, skipAssets } from '@/state/skipClient';
import { getFormattedAssetAmount } from '@/utils/crypto';
import { Wallet } from '@/components/RenderWalletList';
import { iconMap, ICONS } from '@/icons';
Expand Down
4 changes: 2 additions & 2 deletions packages/widget-v2/src/pages/SwapPage/SwapPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { Column } from '@/components/Layout';
import { MainButton } from '@/components/MainButton';
import { SmallText } from '@/components/Typography';
import { ICONS } from '@/icons';
import { skipAssets, getChainsContainingAsset } from '@/state/skip';
import { sourceAssetAtom, destinationAssetAtom } from '@/state/swap';
import { skipAssets, getChainsContainingAsset } from '@/state/skipClient';
import { sourceAssetAtom, destinationAssetAtom } from '@/state/swapPage';
import { TokenAndChainSelectorModal } from '@/modals/TokenAndChainSelectorModal/TokenAndChainSelectorModal';
import { SwapPageSettings } from './SwapPageSettings';
import { SwapPageFooter } from './SwapPageFooter';
Expand Down
15 changes: 15 additions & 0 deletions packages/widget-v2/src/pages/SwapPage/swapPageState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { atom } from 'jotai';
import { ClientAsset } from '@/state/skipClient';
import { Wallet } from '@/components/RenderWalletList';

export type AssetAtom = Partial<ClientAsset> & {
amount?: string;
};

export const sourceAssetAtom = atom<AssetAtom>();

export const destinationAssetAtom = atom<AssetAtom>();

export const connectedWalletAtom = atom<Wallet>();

export const destinationWalletAtom = atom<Wallet>();
7 changes: 7 additions & 0 deletions packages/widget-v2/src/state/errorPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { atomWithReset } from 'jotai/utils';

export const errorAtom = atomWithReset<
ExpectedErrorDetails | Error | undefined
>(undefined);

type ExpectedErrorDetails = {};
8 changes: 8 additions & 0 deletions packages/widget-v2/src/state/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { atom } from 'jotai';

export enum Routes {
SwapPage,
SwapExecutionPage,
}

export const currentPageAtom = atom<Routes>(Routes.SwapPage);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { atom } from 'jotai';
import { ClientAsset } from './skip';
import { ClientAsset } from './skipClient';
import { Wallet } from '@/components/RenderWalletList';

export type AssetAtom = Partial<ClientAsset> & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { Row } from '@/components/Layout';
import { defaultTheme, lightTheme } from '@/widget/theme';
import { ManualAddressModal } from '@/modals/ManualAddressModal/ManualAddressModal';
import { useEffect, useState } from 'react';
import { skipAssets } from '@/state/skip';
import { destinationAssetAtom } from '@/state/swap';
import { skipAssets } from '@/state/skipClient';
import { destinationAssetAtom } from '@/state/swapPage';
import { useAtom } from 'jotai';

const meta = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import type { Meta, StoryObj } from '@storybook/react';
import { renderLightAndDarkTheme } from './renderLightAndDarkTheme';
import { SwapExecutionPage } from '@/pages/SwapExecutionPage/SwapExecutionPage';
import NiceModal from '@ebay/nice-modal-react';
import { destinationAssetAtom } from '@/state/swap';
import { destinationAssetAtom } from '@/state/swapPage';
import { useAtom } from 'jotai';
import operations from '@/pages/SwapExecutionPage/operations.json';
import { skipAssets } from '@/state/skip';
import { skipAssets } from '@/state/skipClient';
import { useEffect, useState } from 'react';
import { Operation } from '@/pages/SwapExecutionPage/SwapExecutionPageRouteDetailedRow';

const meta = {
title: 'Pages/SwapExecutionPage',
Expand All @@ -16,8 +15,8 @@ const meta = {
const [_destinationAsset, setDestinationAsset] =
useAtom(destinationAssetAtom);
const [shouldRender, setShouldRender] = useState(false);
const firstOperation = props.operations[0];
const lastOperation = props.operations[props.operations.length - 1];
const firstOperation = operations[0];
const lastOperation = operations[operations.length - 1];

const [{ data: assets }] = useAtom(skipAssets);

Expand Down Expand Up @@ -57,7 +56,5 @@ type Story = StoryObj<typeof meta>;
export default meta;

export const SwapExecutionPageExample: Story = {
args: {
operations: operations as Operation[],
},
args: {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why you move it inside?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codingki yeah I figure that eventually this data will exist in an atom, so we won't be passing it into the component as a prop, so I decided to just move it inside for now (the usage of the component is more similar to how it'll be when we have the data in an atom)

};
2 changes: 1 addition & 1 deletion packages/widget-v2/src/utils/useUsdValue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import { z } from 'zod';
import { getAssets } from '@/state/skip';
import { getAssets } from '@/state/skipClient';

interface Args {
coingeckoID: string;
Expand Down
31 changes: 31 additions & 0 deletions packages/widget-v2/src/widget/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ErrorPage } from '@/pages/ErrorPage/ErrorPage';
import { SwapExecutionPage } from '@/pages/SwapExecutionPage/SwapExecutionPage';
import { SwapPage } from '@/pages/SwapPage/SwapPage';
import { errorAtom } from '@/state/errorPage';
import { Routes, currentPageAtom } from '@/state/router';
import { useAtom } from 'jotai';
import { ErrorBoundary } from 'react-error-boundary';

export const Router = () => {
const [currentPage] = useAtom(currentPageAtom);
const [error, setError] = useAtom(errorAtom);

if (error) {
return <ErrorPage />;
}

switch (currentPage) {
case Routes.SwapPage:
return (
<ErrorBoundary fallback={null} onError={(error) => setError(error)}>
<SwapPage />
</ErrorBoundary>
);
case Routes.SwapExecutionPage:
return (
<ErrorBoundary fallback={null} onError={(error) => setError(error)}>
<SwapExecutionPage />
</ErrorBoundary>
);
}
};
Comment on lines +1 to +31
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested manually throwing an error within SwapPage and it successfully sets errorAtom state and renders ErrorPage

Copy link
Collaborator Author

@toddkao toddkao Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also tested and can confirm that these error boundaries will not catch any errors thrown within a modal, we will need to handle those separately

6 changes: 3 additions & 3 deletions packages/widget-v2/src/widget/Widget.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ShadowDomAndProviders } from './ShadowDomAndProviders';
import { SwapPage } from '@/pages/SwapPage/SwapPage';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { styled } from 'styled-components';
import { Modal } from '@/components/Modal';
import { cloneElement, ReactElement } from 'react';
import { PartialTheme } from './theme';
import { Router } from './Router';

export type SwapWidgetProps = {
theme?: PartialTheme;
Expand All @@ -15,7 +15,7 @@ export const SwapWidget = (props: SwapWidgetProps) => {
<NiceModal.Provider>
<ShadowDomAndProviders {...props}>
<WidgetContainer>
<SwapPage />
<Router />
</WidgetContainer>
</ShadowDomAndProviders>
</NiceModal.Provider>
Expand All @@ -26,7 +26,7 @@ const SwapWidgetWithoutNiceModalProvider = (props: SwapWidgetProps) => {
return (
<ShadowDomAndProviders {...props}>
<WidgetContainer>
<SwapPage />
<Router />
</WidgetContainer>
</ShadowDomAndProviders>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/widget-v2/tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/* Aliases */
"baseUrl": ".",
"paths": {
"@*": ["src/*"]
"@/*": ["src/*"]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes auto imports / ide from suggesting @components instead of @/components which isn't valid with this config

}
},
"include": ["src"]
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24160,6 +24160,17 @@ __metadata:
languageName: node
linkType: hard

"react-error-boundary@npm:^4.0.13":
version: 4.0.13
resolution: "react-error-boundary@npm:4.0.13"
dependencies:
"@babel/runtime": ^7.12.5
peerDependencies:
react: ">=16.13.1"
checksum: 50398d080015d51d22c6f94c56f4ea336d10232d72345b36ee6f15b6b643666d20b072829b02f091a80e5af68fe67f68a62ef0d2b649dbd759ead929304449af
languageName: node
linkType: hard

"react-hot-toast@npm:^2.4.1":
version: 2.4.1
resolution: "react-hot-toast@npm:2.4.1"
Expand Down Expand Up @@ -28495,6 +28506,7 @@ __metadata:
lodash.debounce: ^4.0.8
pluralize: ^8.0.0
rc-virtual-list: ^3.14.5
react-error-boundary: ^4.0.13
react-shadow-scope: ^1.0.5
storybook: ^8.2.6
styled-components: ^6.0.0
Expand Down
Loading