@rango-dev/widget-embedded 0.20.1-next.6 → 0.20.1-next.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmSwapPage.d.ts","sourceRoot":"","sources":["../../src/pages/ConfirmSwapPage.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAyD5E,wBAAgB,eAAe,sBA2S9B"}
1
+ {"version":3,"file":"ConfirmSwapPage.d.ts","sourceRoot":"","sources":["../../src/pages/ConfirmSwapPage.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAuD,MAAM,OAAO,CAAC;AA0D5E,wBAAgB,eAAe,sBA6S9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"Home.d.ts","sourceRoot":"","sources":["../../src/pages/Home.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AA+C3D,wBAAgB,IAAI,sBAyOnB"}
1
+ {"version":3,"file":"Home.d.ts","sourceRoot":"","sources":["../../src/pages/Home.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AA+C3D,wBAAgB,IAAI,sBA6OnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/widget-embedded",
3
- "version": "0.20.1-next.6",
3
+ "version": "0.20.1-next.8",
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.25.1-next.1",
27
27
  "@rango-dev/queue-manager-react": "^0.24.0",
28
- "@rango-dev/ui": "^0.26.1-next.3",
28
+ "@rango-dev/ui": "^0.26.1-next.4",
29
29
  "@rango-dev/wallets-react": "^0.11.1-next.1",
30
30
  "@rango-dev/wallets-shared": "^0.25.1-next.1",
31
31
  "bignumber.js": "^9.1.1",
@@ -47,4 +47,4 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  }
50
- }
50
+ }
@@ -38,3 +38,15 @@ export const NotificationsBadgeContainer = styled('div', {
38
38
  top: '$0',
39
39
  right: '$0',
40
40
  });
41
+
42
+ export const ProgressIcon = styled('div', {
43
+ padding: '$2',
44
+ variants: {
45
+ isRefetched: {
46
+ true: {
47
+ transform: `rotate(360deg)`,
48
+ transition: 'transform 1s ease-in-out',
49
+ },
50
+ },
51
+ },
52
+ });
@@ -8,5 +8,4 @@ export interface HomeButtonsPropTypes {
8
8
  onClickRefresh?: () => void;
9
9
  onClickHistory?: () => void;
10
10
  onClickSettings?: () => void;
11
- onClickNotifications?: () => void;
12
11
  }
@@ -4,7 +4,6 @@ import { i18n } from '@lingui/core';
4
4
  import {
5
5
  NotificationsIcon,
6
6
  Popover,
7
- RefreshIcon,
8
7
  SettingsIcon,
9
8
  Tooltip,
10
9
  TransactionIcon,
@@ -17,16 +16,11 @@ import { isFeatureHidden } from '../../utils/settings';
17
16
  import { NotificationContent } from '../NotificationContent';
18
17
 
19
18
  import { HeaderButton } from './HeaderButtons.styles';
19
+ import { RefreshButton } from './RefreshButton';
20
20
  import { UnreadNotificationsBadge } from './UnreadNotificationsBadge';
21
21
 
22
22
  export function HomeButtons(props: HomeButtonsPropTypes) {
23
- const {
24
- layoutRef,
25
- onClickRefresh,
26
- onClickHistory,
27
- onClickSettings,
28
- onClickNotifications,
29
- } = props;
23
+ const { layoutRef, onClickRefresh, onClickHistory, onClickSettings } = props;
30
24
 
31
25
  const {
32
26
  config: { features },
@@ -40,35 +34,28 @@ export function HomeButtons(props: HomeButtonsPropTypes) {
40
34
  container={getContainer()}
41
35
  side="top"
42
36
  content={i18n.t('Refresh')}>
43
- <HeaderButton
44
- variant="ghost"
45
- size="small"
46
- onClick={onClickRefresh}
47
- disabled={!onClickRefresh}>
48
- <RefreshIcon size={16} color={!onClickRefresh ? 'gray' : 'black'} />
49
- </HeaderButton>
37
+ <RefreshButton onClick={onClickRefresh} />
50
38
  </Tooltip>
51
39
 
52
40
  {!isNotificationsHidden && (
53
- <Tooltip
41
+ <Popover
42
+ align="center"
43
+ collisionBoundary={layoutRef}
44
+ collisionPadding={{ right: 20, left: 20 }}
54
45
  container={getContainer()}
55
- side="top"
56
- content={i18n.t('Notifications')}>
57
- <Popover
58
- align="center"
59
- collisionBoundary={layoutRef}
60
- collisionPadding={{ right: 20, left: 20 }}
61
- container={getContainer()}
62
- content={<NotificationContent />}>
63
- <HeaderButton
64
- size="small"
65
- variant="ghost"
66
- onClick={onClickNotifications}>
67
- <NotificationsIcon size={18} color="black" />
68
- <UnreadNotificationsBadge />
69
- </HeaderButton>
70
- </Popover>
71
- </Tooltip>
46
+ content={<NotificationContent />}>
47
+ <div>
48
+ <Tooltip
49
+ container={getContainer()}
50
+ side="top"
51
+ content={i18n.t('Notifications')}>
52
+ <HeaderButton size="small" variant="ghost">
53
+ <NotificationsIcon size={18} color="black" />
54
+ <UnreadNotificationsBadge />
55
+ </HeaderButton>
56
+ </Tooltip>
57
+ </div>
58
+ </Popover>
72
59
  )}
73
60
  <Tooltip
74
61
  container={getContainer()}
@@ -0,0 +1,81 @@
1
+ import { RefreshProgressButton } from '@rango-dev/ui';
2
+ import React, { useEffect, useState } from 'react';
3
+
4
+ import { HeaderButton, ProgressIcon } from './HeaderButtons.styles';
5
+
6
+ const REFRESH_INTERVAL = 1000;
7
+ const MAX_ELAPSED_TIME = 60;
8
+ const MAX_PERCENTAGE = 100;
9
+
10
+ function RefreshButton({ onClick }: { onClick: (() => void) | undefined }) {
11
+ const [elapsedTime, setElapsedTime] = useState(0);
12
+ const [isRefetched, setIsRefetched] = useState(false);
13
+
14
+ const handleVisibilityChange = (interval?: number) => {
15
+ if (document.hidden && interval) {
16
+ // Tab is inactive, clear the interval
17
+ clearTimeout(interval);
18
+ }
19
+ };
20
+
21
+ useEffect(() => {
22
+ let interval: number | undefined;
23
+ if (onClick) {
24
+ interval = window.setInterval(() => {
25
+ setElapsedTime((prevTime) => prevTime + 1);
26
+
27
+ if (elapsedTime === MAX_ELAPSED_TIME) {
28
+ handleRefreshClick();
29
+ }
30
+ }, REFRESH_INTERVAL);
31
+ } else {
32
+ clearTimeout(interval);
33
+ }
34
+
35
+ document.addEventListener('visibilitychange', () =>
36
+ handleVisibilityChange(interval)
37
+ );
38
+
39
+ return () => {
40
+ document.removeEventListener('visibilitychange', () =>
41
+ handleVisibilityChange(interval)
42
+ );
43
+ if (interval) {
44
+ clearInterval(interval);
45
+ }
46
+ };
47
+ }, [elapsedTime, onClick]);
48
+
49
+ const clearTimeout = (interval?: number) => {
50
+ if (interval) {
51
+ clearInterval(interval);
52
+ }
53
+ setElapsedTime(0);
54
+ };
55
+
56
+ const handleRefreshClick = () => {
57
+ onClick?.();
58
+ setElapsedTime(0);
59
+ setIsRefetched(true);
60
+ };
61
+
62
+ return (
63
+ <HeaderButton
64
+ variant="ghost"
65
+ size="small"
66
+ onClick={handleRefreshClick}
67
+ disabled={!onClick}>
68
+ <ProgressIcon
69
+ onTransitionEnd={() => setIsRefetched(false)}
70
+ isRefetched={isRefetched}>
71
+ <RefreshProgressButton
72
+ size={24}
73
+ color={!onClick ? 'gray' : 'black'}
74
+ progress={(elapsedTime / MAX_ELAPSED_TIME) * MAX_PERCENTAGE}
75
+ />
76
+ </ProgressIcon>
77
+ </HeaderButton>
78
+ );
79
+ }
80
+
81
+ export { RefreshButton };
@@ -48,6 +48,7 @@ export function useSwapInput(): UseSwapInput {
48
48
  toToken,
49
49
  inputAmount,
50
50
  inputUsdValue,
51
+ quote,
51
52
  resetQuote,
52
53
  setQuote,
53
54
  } = useQuoteStore();
@@ -63,9 +64,9 @@ export function useSwapInput(): UseSwapInput {
63
64
  const [error, setError] = useState<QuoteError | null>(null);
64
65
  const [warning, setWarning] = useState<QuoteWarning | null>(null);
65
66
  const userSlippage = customSlippage ?? slippage;
66
- const hasTokensValue = !fromToken || !toToken;
67
+ const tokensValueInvalid = !fromToken || !toToken;
67
68
  const shouldSkipRequest =
68
- hasTokensValue ||
69
+ tokensValueInvalid ||
69
70
  tokensAreEqual(fromToken, toToken) ||
70
71
  !isPositiveNumber(inputAmount);
71
72
 
@@ -153,6 +154,9 @@ export function useSwapInput(): UseSwapInput {
153
154
  return;
154
155
  }
155
156
  if (shouldSkipRequest) {
157
+ if (quote) {
158
+ resetQuote();
159
+ }
156
160
  return;
157
161
  }
158
162
  resetQuote();
@@ -12,7 +12,6 @@ import {
12
12
  css,
13
13
  Divider,
14
14
  IconButton,
15
- RefreshIcon,
16
15
  SettingsIcon,
17
16
  styled,
18
17
  Tooltip,
@@ -26,6 +25,7 @@ import { useNavigate } from 'react-router-dom';
26
25
  import { getRequiredWallets } from '../components/ConfirmWalletsModal/ConfirmWallets.helpers';
27
26
  import { ConfirmWalletsModal } from '../components/ConfirmWalletsModal/ConfirmWalletsModal';
28
27
  import { HeaderButton } from '../components/HeaderButtons/HeaderButtons.styles';
28
+ import { RefreshButton } from '../components/HeaderButtons/RefreshButton';
29
29
  import { Layout } from '../components/Layout';
30
30
  import { navigationRoutes } from '../constants/navigationRoutes';
31
31
  import { getQuoteUpdateWarningMessage } from '../constants/warnings';
@@ -324,15 +324,17 @@ export function ConfirmSwapPage() {
324
324
  <Typography variant="title" size="small">
325
325
  {i18n.t('You get')}
326
326
  </Typography>
327
- <Button
328
- style={{ padding: '0' }}
329
- variant="ghost"
330
- disabled={fetchingConfirmationQuote}
331
- onClick={onRefresh}>
332
- <div className={iconStyles()}>
333
- <RefreshIcon size={16} />
334
- </div>
335
- </Button>
327
+ <div className={iconStyles()}>
328
+ <RefreshButton
329
+ onClick={
330
+ !fetchingConfirmationQuote &&
331
+ !showWallets &&
332
+ !showQuoteWarningModal
333
+ ? onRefresh
334
+ : undefined
335
+ }
336
+ />
337
+ </div>
336
338
  </div>
337
339
  {dbErrorMessage && (
338
340
  <>
@@ -161,7 +161,11 @@ export function Home() {
161
161
  suffix: (
162
162
  <HomeButtons
163
163
  layoutRef={layoutRef.current}
164
- onClickRefresh={!!quote || quoteError ? fetchQuote : undefined}
164
+ onClickRefresh={
165
+ (!!quote || quoteError) && !showQuoteWarningModal
166
+ ? fetchQuote
167
+ : undefined
168
+ }
165
169
  onClickHistory={() => navigate(navigationRoutes.swaps)}
166
170
  onClickSettings={() => navigate(navigationRoutes.settings)}
167
171
  />