@rango-dev/widget-embedded 0.21.1-next.2 → 0.21.1-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/components/ConfirmWalletsModal/ConfirmWallets.styles.d.ts +1 -1
  2. package/dist/components/HistoryGroupedList/HistoryGroupedList.d.ts +4 -0
  3. package/dist/components/HistoryGroupedList/HistoryGroupedList.d.ts.map +1 -0
  4. package/dist/components/HistoryGroupedList/HistoryGroupedList.helpers.d.ts +2 -0
  5. package/dist/components/HistoryGroupedList/HistoryGroupedList.helpers.d.ts.map +1 -0
  6. package/dist/components/{SwapsGroup/SwapsGroup.styles.d.ts → HistoryGroupedList/HistoryGroupedList.styles.d.ts} +162 -1
  7. package/dist/components/HistoryGroupedList/HistoryGroupedList.styles.d.ts.map +1 -0
  8. package/dist/components/{SwapsGroup/SwapsGroup.types.d.ts → HistoryGroupedList/HistoryGroupedList.types.d.ts} +5 -4
  9. package/dist/components/HistoryGroupedList/HistoryGroupedList.types.d.ts.map +1 -0
  10. package/dist/components/HistoryGroupedList/index.d.ts +2 -0
  11. package/dist/components/HistoryGroupedList/index.d.ts.map +1 -0
  12. package/dist/components/NotificationContent/NotificationContent.d.ts.map +1 -1
  13. package/dist/components/TokenList/TokenList.d.ts.map +1 -1
  14. package/dist/index.js +2 -2
  15. package/dist/index.js.map +4 -4
  16. package/dist/types/notification.d.ts +4 -4
  17. package/dist/types/notification.d.ts.map +1 -1
  18. package/dist/utils/date.d.ts +1 -1
  19. package/dist/utils/date.d.ts.map +1 -1
  20. package/dist/utils/wallets.d.ts +1 -1
  21. package/package.json +2 -2
  22. package/readme.md +1 -0
  23. package/src/components/HistoryGroupedList/HistoryGroupedList.helpers.ts +17 -0
  24. package/src/components/{SwapsGroup/SwapsGroup.styles.ts → HistoryGroupedList/HistoryGroupedList.styles.ts} +9 -0
  25. package/src/components/HistoryGroupedList/HistoryGroupedList.tsx +168 -0
  26. package/src/components/{SwapsGroup/SwapsGroup.types.ts → HistoryGroupedList/HistoryGroupedList.types.ts} +4 -3
  27. package/src/components/HistoryGroupedList/index.ts +1 -0
  28. package/src/components/NotificationContent/NotificationContent.tsx +13 -22
  29. package/src/components/NotificationContent/NotificationNotFound.tsx +1 -1
  30. package/src/components/TokenList/TokenList.tsx +4 -24
  31. package/src/hooks/useSwapInput.ts +2 -2
  32. package/src/hooks/useSyncStoresWithConfig.ts +3 -3
  33. package/src/pages/HistoryPage.tsx +6 -6
  34. package/src/store/notification.ts +4 -4
  35. package/src/store/slices/data.ts +2 -2
  36. package/src/types/notification.ts +4 -4
  37. package/src/utils/configs.ts +3 -3
  38. package/src/utils/date.ts +9 -2
  39. package/src/utils/meta.ts +2 -2
  40. package/src/utils/wallets.ts +1 -1
  41. package/dist/components/SwapsGroup/SwapsGroup.d.ts +0 -4
  42. package/dist/components/SwapsGroup/SwapsGroup.d.ts.map +0 -1
  43. package/dist/components/SwapsGroup/SwapsGroup.styles.d.ts.map +0 -1
  44. package/dist/components/SwapsGroup/SwapsGroup.types.d.ts.map +0 -1
  45. package/dist/components/SwapsGroup/index.d.ts +0 -2
  46. package/dist/components/SwapsGroup/index.d.ts.map +0 -1
  47. package/src/components/SwapsGroup/SwapsGroup.tsx +0 -141
  48. package/src/components/SwapsGroup/index.ts +0 -1
@@ -2,13 +2,13 @@ import { type Route, type RouteEvent, type Step, type StepEvent } from '@rango-d
2
2
  type NotificationRoute = {
3
3
  from: {
4
4
  blockchain: Step['fromBlockchain'];
5
- tokenSymbol: Step['fromSymbol'];
6
- tokenAddress: Step['fromSymbolAddress'];
5
+ symbol: Step['fromSymbol'];
6
+ address: Step['fromSymbolAddress'];
7
7
  };
8
8
  to: {
9
9
  blockchain: Step['toBlockchain'];
10
- tokenSymbol: Step['toSymbol'];
11
- tokenAddress: Step['toSymbolAddress'];
10
+ symbol: Step['toSymbol'];
11
+ address: Step['toSymbolAddress'];
12
12
  };
13
13
  };
14
14
  export type Notification = Pick<Route, 'requestId'> & {
@@ -1 +1 @@
1
- {"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../src/types/notification.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,SAAS,EACf,MAAM,uCAAuC,CAAC;AAE/C,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE;QACJ,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAChC,YAAY,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;KACzC,CAAC;IACF,EAAE,EAAE;QACF,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACjC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9B,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;KACvC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG;IACpD,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,iBAAiB,CAAC;CAC1B,CAAC"}
1
+ {"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../src/types/notification.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,SAAS,EACf,MAAM,uCAAuC,CAAC;AAE/C,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE;QACJ,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3B,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;KACpC,CAAC;IACF,EAAE,EAAE;QACF,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACjC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACzB,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;KAClC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG;IACpD,KAAK,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,iBAAiB,CAAC;CAC1B,CAAC"}
@@ -1,3 +1,3 @@
1
- import type { GroupBy } from '../components/SwapsGroup/SwapsGroup.types';
1
+ import type { GroupBy } from '../components/HistoryGroupedList/HistoryGroupedList.types';
2
2
  export declare const groupSwapsByDate: GroupBy;
3
3
  //# sourceMappingURL=date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC;AAMzE,eAAO,MAAM,gBAAgB,EAAE,OAmE9B,CAAC"}
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2DAA2D,CAAC;AAMzF,eAAO,MAAM,gBAAgB,EAAE,OA0E9B,CAAC"}
@@ -18,7 +18,7 @@ export declare const isExperimentalChain: (blockchains: BlockchainMeta[], wallet
18
18
  export declare const getKeplrCompatibleConnectedWallets: (selectableWallets: Wallet[]) => WalletType[];
19
19
  export declare function formatBalance(balance: Balance | null): Balance | null;
20
20
  export declare function sortTokens(tokens: Token[], getBalanceFor: (token: Token) => Balance | null, isTokenPinned: (token: Token) => boolean): Token[];
21
- export declare function tokensAreEqual(tokenA: Pick<Token, 'blockchain' | 'symbol' | 'address'> | null, tokenB: Pick<Token, 'blockchain' | 'symbol' | 'address'> | null): boolean;
21
+ export declare function areTokensEqual(tokenA: Pick<Token, 'blockchain' | 'symbol' | 'address'> | null, tokenB: Pick<Token, 'blockchain' | 'symbol' | 'address'> | null): boolean;
22
22
  export declare function sortWalletsBasedOnConnectionState(wallets: ModalWalletInfo[]): ModalWalletInfo[];
23
23
  export declare function getConciseAddress(address: string, maxChars?: number, ellipsisLength?: number): string;
24
24
  export declare function getAddress({ chain, connectedWallets, walletType, }: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.21.1-next.2",
3
+ "version": "0.21.1-next.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "source": "./src/index.ts",
@@ -25,7 +25,7 @@
25
25
  "@rango-dev/queue-manager-core": "^0.25.0",
26
26
  "@rango-dev/queue-manager-rango-preset": "^0.26.0",
27
27
  "@rango-dev/queue-manager-react": "^0.25.0",
28
- "@rango-dev/ui": "^0.27.1-next.1",
28
+ "@rango-dev/ui": "^0.27.1-next.3",
29
29
  "@rango-dev/wallets-react": "^0.12.0",
30
30
  "@rango-dev/wallets-shared": "^0.26.0",
31
31
  "bignumber.js": "^9.1.1",
package/readme.md CHANGED
@@ -1,3 +1,4 @@
1
1
  # @rango-dev/widget-embedded
2
2
 
3
3
  Rango Embedded Widget
4
+
@@ -0,0 +1,17 @@
1
+ /*
2
+ * The calculateGroupsSoFar Slices the total groups into the groups which contain the items so far.
3
+ * For example, if you have [10, 10, 10, 10] groups in total,
4
+ * slicing them to 23 will result in [10, 10, 3] :
5
+ * https://virtuoso.dev/grouped-with-load-on-demand/
6
+ */
7
+ export function calculateGroupsSoFar(totalGroups: number[], count: number) {
8
+ const groups: number[] = [];
9
+ let index = 0;
10
+ do {
11
+ const group = totalGroups[index];
12
+ groups.push(Math.min(group, count));
13
+ count -= group;
14
+ index++;
15
+ } while (count > 0 && index <= totalGroups.length);
16
+ return groups;
17
+ }
@@ -2,10 +2,19 @@ import { css, darkTheme, styled } from '@rango-dev/ui';
2
2
 
3
3
  export const groupStyles = css();
4
4
 
5
+ export const SwapItemContainer = styled('div', {
6
+ display: 'flex',
7
+ justifyContent: 'center',
8
+ alignItems: 'center',
9
+ padding: '$5',
10
+ });
11
+
5
12
  export const Group = styled('div', {
6
13
  width: '100%',
7
14
  display: 'flex',
8
15
  flexDirection: 'column',
16
+ backgroundColor: '$background',
17
+ padding: '$10 $5 0 $5',
9
18
  [`& .${groupStyles}`]: {
10
19
  $$color: '$colors$neutral600',
11
20
  [`.${darkTheme} &`]: {
@@ -0,0 +1,168 @@
1
+ import type { PropTypes } from './HistoryGroupedList.types';
2
+
3
+ import { i18n } from '@lingui/core';
4
+ import {
5
+ Divider,
6
+ GroupedVirtualizedList,
7
+ SwapListItem,
8
+ Typography,
9
+ } from '@rango-dev/ui';
10
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
11
+
12
+ import {
13
+ TOKEN_AMOUNT_MAX_DECIMALS,
14
+ TOKEN_AMOUNT_MIN_DECIMALS,
15
+ } from '../../constants/routing';
16
+ import { getContainer } from '../../utils/common';
17
+ import { formatTooltipNumbers, numberToString } from '../../utils/numbers';
18
+
19
+ import { calculateGroupsSoFar } from './HistoryGroupedList.helpers';
20
+ import {
21
+ Group,
22
+ groupStyles,
23
+ SwapItemContainer,
24
+ SwapList,
25
+ Time,
26
+ } from './HistoryGroupedList.styles';
27
+
28
+ const ITEMS_PER_PAGE = 10;
29
+
30
+ export function HistoryGroupedList(props: PropTypes) {
31
+ const { list, onSwapClick, groupBy, isLoading } = props;
32
+ const [currentGroupCounts, setCurrentGroupCounts] = useState<number[]>([]);
33
+ const loadedItems = useRef(0);
34
+ const { swaps, groupCounts, groups } = groupBy(list);
35
+
36
+ const calculateGroups = useCallback(calculateGroupsSoFar, []);
37
+
38
+ const loadMore = useCallback(() => {
39
+ const remainedItems = list.length - loadedItems.current;
40
+ if (remainedItems) {
41
+ loadedItems.current += Math.min(remainedItems, ITEMS_PER_PAGE);
42
+ setCurrentGroupCounts(calculateGroups(groupCounts, loadedItems.current));
43
+ }
44
+ }, [list.length]);
45
+
46
+ useEffect(() => {
47
+ if (!isLoading) {
48
+ loadMore();
49
+ }
50
+ }, [isLoading, loadMore]);
51
+
52
+ if (isLoading) {
53
+ const swaps = [{}, {}];
54
+
55
+ const loadingGroups = [
56
+ {
57
+ title: i18n.t('Today'),
58
+ swaps,
59
+ },
60
+ {
61
+ title: i18n.t('This month'),
62
+ swaps,
63
+ },
64
+ ];
65
+ return (
66
+ <>
67
+ {loadingGroups.map((group) => (
68
+ <Group key={group.title}>
69
+ <Time>
70
+ <Typography
71
+ variant="label"
72
+ size="medium"
73
+ className={groupStyles()}>
74
+ {group.title}
75
+ </Typography>
76
+ </Time>
77
+ <Divider size={4} />
78
+ <SwapList>
79
+ {group.swaps.map((_, index) => {
80
+ const key = index + group.title;
81
+ return <SwapListItem isLoading={true} key={key} />;
82
+ })}
83
+ </SwapList>
84
+ </Group>
85
+ ))}
86
+ </>
87
+ );
88
+ }
89
+
90
+ return (
91
+ <GroupedVirtualizedList
92
+ endReached={() => {
93
+ if (loadedItems.current < list.length) {
94
+ loadMore();
95
+ }
96
+ }}
97
+ groupCounts={currentGroupCounts}
98
+ groupContent={(index) => {
99
+ return (
100
+ <Group>
101
+ <Time>
102
+ <Typography
103
+ variant="label"
104
+ size="medium"
105
+ className={groupStyles()}>
106
+ {groups[index]}
107
+ </Typography>
108
+ </Time>
109
+ </Group>
110
+ );
111
+ }}
112
+ itemContent={(index, groupIndex) => {
113
+ const swap = swaps[index];
114
+ const firstStep = swap.steps[0];
115
+ const lastStep = swap.steps[swap.steps.length - 1];
116
+ return (
117
+ <SwapItemContainer key={swap.requestId}>
118
+ <SwapListItem
119
+ requestId={swap.requestId}
120
+ creationTime={swap.creationTime}
121
+ status={swap.status}
122
+ onClick={onSwapClick}
123
+ tooltipContainer={getContainer()}
124
+ onlyShowTime={groups[groupIndex] === i18n.t('Today')}
125
+ swapTokenData={{
126
+ from: {
127
+ token: {
128
+ image: firstStep.fromLogo,
129
+ displayName: firstStep.fromSymbol,
130
+ },
131
+ blockchain: {
132
+ image: firstStep.fromBlockchainLogo || '',
133
+ },
134
+ amount: numberToString(
135
+ swap.inputAmount,
136
+ TOKEN_AMOUNT_MIN_DECIMALS,
137
+ TOKEN_AMOUNT_MAX_DECIMALS
138
+ ),
139
+ realAmount: formatTooltipNumbers(swap.inputAmount),
140
+ },
141
+ to: {
142
+ token: {
143
+ image: lastStep.toLogo,
144
+ displayName: lastStep.toSymbol,
145
+ },
146
+ blockchain: {
147
+ image: lastStep.toBlockchainLogo || '',
148
+ },
149
+ amount: numberToString(
150
+ lastStep.outputAmount ||
151
+ lastStep.expectedOutputAmountHumanReadable ||
152
+ '',
153
+ TOKEN_AMOUNT_MIN_DECIMALS,
154
+ TOKEN_AMOUNT_MAX_DECIMALS
155
+ ),
156
+ realAmount: formatTooltipNumbers(
157
+ lastStep.outputAmount ||
158
+ lastStep.expectedOutputAmountHumanReadable
159
+ ),
160
+ },
161
+ }}
162
+ />
163
+ </SwapItemContainer>
164
+ );
165
+ }}
166
+ />
167
+ );
168
+ }
@@ -1,13 +1,14 @@
1
1
  import type { PendingSwap } from 'rango-types';
2
2
 
3
3
  export type GroupBy = (list: PendingSwap[]) => {
4
- title: string;
5
4
  swaps: PendingSwap[];
6
- }[];
5
+ groups: string[];
6
+ groupCounts: number[];
7
+ };
7
8
 
8
9
  export interface PropTypes {
9
10
  list: PendingSwap[];
10
11
  onSwapClick: (requestId: string) => void;
11
- groupBy?: GroupBy;
12
+ groupBy: GroupBy;
12
13
  isLoading: boolean;
13
14
  }
@@ -0,0 +1 @@
1
+ export { HistoryGroupedList } from './HistoryGroupedList';
@@ -14,6 +14,7 @@ import { useNavigate } from 'react-router-dom';
14
14
  import { navigationRoutes } from '../../constants/navigationRoutes';
15
15
  import { useAppStore } from '../../store/AppStore';
16
16
  import { useNotificationStore } from '../../store/notification';
17
+ import { areTokensEqual } from '../../utils/wallets';
17
18
 
18
19
  import { Container, Images, List } from './NotificationContent.styles';
19
20
  import { NotificationNotFound } from './NotificationNotFound';
@@ -41,50 +42,40 @@ export function NotificationContent() {
41
42
  {sortedNotification.length ? (
42
43
  <List>
43
44
  {sortedNotification.map((notificationItem) => {
44
- const fromToken = tokens.find(
45
- (tokenItem) =>
46
- tokenItem.address ===
47
- notificationItem.route.from.tokenAddress &&
48
- tokenItem.blockchain ===
49
- notificationItem.route.from.blockchain &&
50
- tokenItem.symbol === notificationItem.route.from.tokenSymbol
45
+ const { route, requestId, event } = notificationItem;
46
+ const fromToken = tokens.find((tokenItem) =>
47
+ areTokensEqual(tokenItem, route.from)
51
48
  );
52
49
 
53
50
  const fromBlockchain = blockchains.find(
54
- (blockchainItem) =>
55
- blockchainItem.name === notificationItem.route.from.blockchain
51
+ (blockchainItem) => blockchainItem.name === route.from.blockchain
56
52
  );
57
53
 
58
- const toToken = tokens.find(
59
- (tokenItem) =>
60
- tokenItem.address === notificationItem.route.to.tokenAddress &&
61
- tokenItem.blockchain === notificationItem.route.to.blockchain &&
62
- tokenItem.symbol === notificationItem.route.to.tokenSymbol
54
+ const toToken = tokens.find((tokenItem) =>
55
+ areTokensEqual(tokenItem, route.to)
63
56
  );
64
57
 
65
58
  const toBlockchain = blockchains.find(
66
- (blockchainItem) =>
67
- blockchainItem.name === notificationItem.route.to.blockchain
59
+ (blockchainItem) => blockchainItem.name === route.to.blockchain
68
60
  );
69
61
 
70
62
  return (
71
63
  <ListItemButton
72
- key={notificationItem.requestId}
73
- onClick={() => handleOnClick(notificationItem.requestId)}
64
+ key={requestId}
65
+ onClick={() => handleOnClick(requestId)}
74
66
  title={
75
67
  <Typography
76
68
  variant="body"
77
69
  size="small"
78
70
  color={
79
- notificationItem.event.messageSeverity ===
80
- EventSeverity.WARNING
71
+ event.messageSeverity === EventSeverity.WARNING
81
72
  ? '$foreground'
82
73
  : '$neutral700'
83
74
  }>
84
- {i18n.t(notificationItem.event.message)}
75
+ {i18n.t(event.message)}
85
76
  </Typography>
86
77
  }
87
- id={notificationItem.requestId}
78
+ id={requestId}
88
79
  start={
89
80
  <Images>
90
81
  <div className="from-chain-token">
@@ -10,7 +10,7 @@ export function NotificationNotFound() {
10
10
  <NoNotificationIcon color="secondary" size={26} />
11
11
  <Divider size={12} />
12
12
  <Typography variant="body" size="medium" color="neutral700">
13
- {i18n.t('You have no notification')}
13
+ {i18n.t('There are no notifications.')}
14
14
  </Typography>
15
15
  </NotFoundContainer>
16
16
  );
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-magic-numbers */
2
2
  import type { PropTypes, RenderDescProps } from './TokenList.types';
3
3
  import type { Token } from 'rango-sdk';
4
- import type { CommonProps } from 'react-window';
5
4
 
6
5
  import { i18n } from '@lingui/core';
7
6
  import {
@@ -16,7 +15,7 @@ import {
16
15
  Typography,
17
16
  VirtualizedList,
18
17
  } from '@rango-dev/ui';
19
- import React, { forwardRef, useEffect, useState } from 'react';
18
+ import React, { useEffect, useState } from 'react';
20
19
 
21
20
  import { useAppStore } from '../../store/AppStore';
22
21
  import { useWalletsStore } from '../../store/wallets';
@@ -100,20 +99,6 @@ export function TokenList(props: PropTypes) {
100
99
  const { getBalanceFor, loading: loadingWallet } = useWalletsStore();
101
100
  const { isTokenPinned } = useAppStore();
102
101
 
103
- // eslint-disable-next-line react/display-name
104
- const innerElementType: React.FC<CommonProps> = forwardRef((render, ref) => {
105
- return (
106
- <div
107
- {...render}
108
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
- ref={ref as any}
110
- style={{
111
- ...render.style,
112
- height: `${parseFloat(render.style?.height as string) + 8 * 2}px`,
113
- }}
114
- />
115
- );
116
- });
117
102
  const loadNextPage = () => {
118
103
  setTokens(list.slice(0, tokens.length + PAGE_SIZE));
119
104
  };
@@ -140,7 +125,8 @@ export function TokenList(props: PropTypes) {
140
125
  }
141
126
  return (
142
127
  <VirtualizedList
143
- Item={({ index, style }) => {
128
+ endReached={hasNextPage ? loadNextPage : undefined}
129
+ itemContent={(index) => {
144
130
  const token = tokens[index];
145
131
  const tokenBalance = formatBalance(getBalanceFor(token));
146
132
  const address = token.address || '';
@@ -171,12 +157,10 @@ export function TokenList(props: PropTypes) {
171
157
  return (
172
158
  <div
173
159
  style={{
174
- ...style,
175
160
  paddingRight: 5,
176
161
  }}>
177
162
  <ListItemButton
178
163
  style={{
179
- height: style?.height,
180
164
  width: '100%',
181
165
  overflow: 'hidden',
182
166
  }}
@@ -261,11 +245,7 @@ export function TokenList(props: PropTypes) {
261
245
  </div>
262
246
  );
263
247
  }}
264
- hasNextPage={hasNextPage}
265
- itemCount={tokens.length}
266
- loadNextPage={loadNextPage}
267
- innerElementType={innerElementType}
268
- size={60}
248
+ totalCount={tokens.length}
269
249
  key={`${selectedBlockchain}-${searchedFor}`}
270
250
  />
271
251
  );
@@ -11,7 +11,7 @@ import { isPositiveNumber } from '../utils/numbers';
11
11
  import { generateQuoteWarnings } from '../utils/quote';
12
12
  import { isFeatureEnabled } from '../utils/settings';
13
13
  import { createQuoteRequestBody } from '../utils/swap';
14
- import { tokensAreEqual } from '../utils/wallets';
14
+ import { areTokensEqual } from '../utils/wallets';
15
15
 
16
16
  import {
17
17
  handleQuoteErrors,
@@ -68,7 +68,7 @@ export function useSwapInput(): UseSwapInput {
68
68
  const tokensValueInvalid = !fromToken || !toToken;
69
69
  const shouldSkipRequest =
70
70
  tokensValueInvalid ||
71
- tokensAreEqual(fromToken, toToken) ||
71
+ areTokensEqual(fromToken, toToken) ||
72
72
  !isPositiveNumber(inputAmount);
73
73
 
74
74
  const resetState = (loading: boolean) => {
@@ -8,7 +8,7 @@ import {
8
8
  isBlockchainExcludedInConfig,
9
9
  isTokenExcludedInConfig,
10
10
  } from '../utils/configs';
11
- import { tokensAreEqual } from '../utils/wallets';
11
+ import { areTokensEqual } from '../utils/wallets';
12
12
 
13
13
  export function useSyncStoresWithConfig() {
14
14
  const {
@@ -50,7 +50,7 @@ export function useSyncStoresWithConfig() {
50
50
  (chain) => chain.name === config?.from?.blockchain
51
51
  );
52
52
  const token = tokens.find((t) =>
53
- tokensAreEqual(t, config?.from?.token || null)
53
+ areTokensEqual(t, config?.from?.token || null)
54
54
  );
55
55
 
56
56
  if (chain || (!chain && prevConfigFromBlockchain.current)) {
@@ -99,7 +99,7 @@ export function useSyncStoresWithConfig() {
99
99
  (chain) => chain.name === config?.to?.blockchain
100
100
  );
101
101
  const token = tokens.find((t) =>
102
- tokensAreEqual(t, config?.to?.token || null)
102
+ areTokensEqual(t, config?.to?.token || null)
103
103
  );
104
104
 
105
105
  if (chain || (!chain && prevConfigToBlockchain.current)) {
@@ -6,15 +6,15 @@ import { Divider, NotFound, styled } from '@rango-dev/ui';
6
6
  import React, { useState } from 'react';
7
7
  import { useNavigate } from 'react-router-dom';
8
8
 
9
+ import { HistoryGroupedList } from '../components/HistoryGroupedList';
10
+ import { NotFoundContainer } from '../components/HistoryGroupedList/HistoryGroupedList.styles';
9
11
  import { Layout, PageContainer } from '../components/Layout';
10
12
  import { SearchInput } from '../components/SearchInput';
11
- import { SwapsGroup } from '../components/SwapsGroup';
12
- import { NotFoundContainer } from '../components/SwapsGroup/SwapsGroup.styles';
13
13
  import { groupSwapsByDate } from '../utils/date';
14
14
  import { containsText } from '../utils/numbers';
15
15
  import { getPendingSwaps } from '../utils/queue';
16
16
 
17
- const SwapsGroupContainer = styled('div', {
17
+ const HistoryGroupedListContainer = styled('div', {
18
18
  overflowY: 'visible',
19
19
  width: '100%',
20
20
  display: 'flex',
@@ -77,7 +77,7 @@ export function HistoryPage() {
77
77
  value={searchedFor}
78
78
  />
79
79
  <Divider size="16" />
80
- <SwapsGroupContainer>
80
+ <HistoryGroupedListContainer>
81
81
  {isEmpty && (
82
82
  <NotFoundContainer>
83
83
  <Divider size={32} />
@@ -90,14 +90,14 @@ export function HistoryPage() {
90
90
  </NotFoundContainer>
91
91
  )}
92
92
  {!isEmpty && (
93
- <SwapsGroup
93
+ <HistoryGroupedList
94
94
  list={filteredList}
95
95
  onSwapClick={navigate}
96
96
  groupBy={groupSwapsByDate}
97
97
  isLoading={loading}
98
98
  />
99
99
  )}
100
- </SwapsGroupContainer>
100
+ </HistoryGroupedListContainer>
101
101
  </PageContainer>
102
102
  </Layout>
103
103
  );
@@ -34,13 +34,13 @@ export const useNotificationStore = createSelectors(
34
34
  route: {
35
35
  from: {
36
36
  blockchain: fromStep.fromBlockchain,
37
- tokenAddress: fromStep.fromSymbolAddress,
38
- tokenSymbol: fromStep.fromSymbol,
37
+ address: fromStep.fromSymbolAddress,
38
+ symbol: fromStep.fromSymbol,
39
39
  },
40
40
  to: {
41
41
  blockchain: toStep.toBlockchain,
42
- tokenSymbol: toStep.toSymbol,
43
- tokenAddress: toStep.toSymbolAddress,
42
+ address: toStep.toSymbolAddress,
43
+ symbol: toStep.toSymbol,
44
44
  },
45
45
  },
46
46
  };
@@ -8,7 +8,7 @@ import { httpService as sdk } from '../../services/httpService';
8
8
  import { containsText } from '../../utils/common';
9
9
  import { isTokenExcludedInConfig } from '../../utils/configs';
10
10
  import { sortLiquiditySourcesByGroupTitle } from '../../utils/settings';
11
- import { tokensAreEqual } from '../../utils/wallets';
11
+ import { areTokensEqual } from '../../utils/wallets';
12
12
 
13
13
  type BlockchainOptions = {
14
14
  type?: 'source' | 'destination';
@@ -163,7 +163,7 @@ export const createDataSlice: StateCreator<
163
163
  ? get().config.from?.pinnedTokens
164
164
  : get().config.to?.pinnedTokens;
165
165
  const pinned = !!pinnedTokens?.some((pinnedToken) =>
166
- tokensAreEqual(pinnedToken, token)
166
+ areTokensEqual(pinnedToken, token)
167
167
  );
168
168
  return pinned;
169
169
  },
@@ -8,13 +8,13 @@ import {
8
8
  type NotificationRoute = {
9
9
  from: {
10
10
  blockchain: Step['fromBlockchain'];
11
- tokenSymbol: Step['fromSymbol'];
12
- tokenAddress: Step['fromSymbolAddress'];
11
+ symbol: Step['fromSymbol'];
12
+ address: Step['fromSymbolAddress'];
13
13
  };
14
14
  to: {
15
15
  blockchain: Step['toBlockchain'];
16
- tokenSymbol: Step['toSymbol'];
17
- tokenAddress: Step['toSymbolAddress'];
16
+ symbol: Step['toSymbol'];
17
+ address: Step['toSymbolAddress'];
18
18
  };
19
19
  };
20
20
 
@@ -3,7 +3,7 @@ import type { Asset, BlockchainMeta, Token } from 'rango-sdk';
3
3
 
4
4
  import { RANGO_PUBLIC_API_KEY } from '../constants';
5
5
 
6
- import { tokensAreEqual } from './wallets';
6
+ import { areTokensEqual } from './wallets';
7
7
 
8
8
  export interface Configs {
9
9
  API_KEY: string;
@@ -57,10 +57,10 @@ export const isTokenExcludedInConfig = (
57
57
  let result = false;
58
58
  if (tokensConfig && token) {
59
59
  if (Array.isArray(tokensConfig)) {
60
- result = !tokensConfig.some((asset) => tokensAreEqual(asset, token));
60
+ result = !tokensConfig.some((asset) => areTokensEqual(asset, token));
61
61
  } else if (!Array.isArray(tokensConfig) && tokensConfig[token.blockchain]) {
62
62
  result = tokensConfig[token.blockchain].tokens.some((asset) =>
63
- tokensAreEqual(asset, token)
63
+ areTokensEqual(asset, token)
64
64
  );
65
65
  const isExcluded = tokensConfig[token.blockchain].isExcluded;
66
66
  return (!isExcluded && !result) || (isExcluded && result);
package/src/utils/date.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { GroupBy } from '../components/SwapsGroup/SwapsGroup.types';
1
+ import type { GroupBy } from '../components/HistoryGroupedList/HistoryGroupedList.types';
2
2
  import type { PendingSwap } from 'rango-types';
3
3
 
4
4
  import { i18n } from '@lingui/core';
@@ -70,5 +70,12 @@ export const groupSwapsByDate: GroupBy = (swaps) => {
70
70
  }
71
71
  });
72
72
 
73
- return Array.from(output.values());
73
+ const groupedSwaps = Array.from(output.values()).filter(
74
+ (item) => item.swaps.length > 0
75
+ );
76
+ const items = groupedSwaps.flatMap((group) => group.swaps);
77
+ const groupCounts = groupedSwaps.map((group) => group.swaps.length);
78
+ const groups = groupedSwaps.map((group) => group.title);
79
+
80
+ return { swaps: items, groupCounts, groups };
74
81
  };
package/src/utils/meta.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Asset, BlockchainMeta, SwapperMeta, Token } from 'rango-sdk';
2
2
 
3
- import { tokensAreEqual } from './wallets';
3
+ import { areTokensEqual } from './wallets';
4
4
 
5
5
  export function getBlockchainDisplayNameFor(
6
6
  blockchainName: string,
@@ -25,7 +25,7 @@ export function getSwapperDisplayName(
25
25
  }
26
26
 
27
27
  export function findToken(t: Asset, tokens: Token[]) {
28
- return tokens.find((token) => tokensAreEqual(token, t)) ?? null;
28
+ return tokens.find((token) => areTokensEqual(token, t)) ?? null;
29
29
  }
30
30
 
31
31
  export function findBlockchain(name: string, blockchains: BlockchainMeta[]) {